Medusa 는 내부적으로 select / poll 를 이용, 비동기 소켓부분을 구현한다. 소켓 이벤트들 처리에 대한 인터페이스가 아주 깔끔. 참 마음에 든다.
MFC 의
CSocket 를 사용하는 스타일로 프로그래밍을 할 수 있는데, Python 이기에 코드가 더 깔끔. 그리고 Windows/Linux 양쪽 다 가능.
다음은 화일 보내는 부분과 관련한 간단한 예제.
~cpp
import asyncore
import socket
from threading import *
import os
import os.path
class FileSendChannel(asyncore.dispatcher, Thread):
def __init__(self, aConnection, anAddress):
asyncore.dispatcher.__init__(self, aConnection)
Thread.__init__(self)
print "file send channel create."
print "address :", anAddress
self.address = anAddress
def run(self):
print "file send channel start."
self.fileSendMain()
def writable(self):
return not self.connected
def handle_read(self):
bufferSize=8192
data = self.recv(bufferSize)
print "data :", data
def handle_close(self):
self.close()
print "closed channel..."
def getFileSize(self, aFileName):
return os.path.getsize(aFileName)
def fileSendMain(self):
aFileName='f:/sample.jpg'
fileSize=self.getFileSize(aFileName)
print "file size : ", fileSize
f = open(aFileName, "rb")
print "file opened.."
currentReaded=0
while currentReaded < fileSize:
data = f.read(1024)
#currentReaded = f.tell()
sended = self.send(data)
currentReaded+=sended
f.seek(currentReaded, 0)
print "current : %d, sended : %d"%(currentReaded, sended)
f.close()
print "send completed..."
self.close()
class FileSendServer(asyncore.dispatcher):
def __init__(self):
asyncore.dispatcher.__init__(self)
def initialize(self):
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
def handle_accept(self):
connection, address = self.accept()
channel = FileSendChannel(connection, address)
channel.start()
def handle_close(self):
pass
def handle_read(self):
pass
def handle_write(self):
pass
def serve(self, aPort):
self.initialize()
here = ('', aPort)
self.bind(here)
self.listen(5)
if __name__=='__main__':
server = FileSendServer()
server.serve(30002)
asyncore.loop()
다음은 화일 받는 부분과 관련한 간단한 예제.
~cpp
import asyncore
import socket
class FileReceiveChannel(asyncore.dispatcher):
def __init__(self):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.received = 0
self.f=open("f://output1.jpg","wb")
def handle_connect(self):
print "connected..."
def writable(self):
return not self.connected
def handle_write(self):
pass
def handle_read(self):
data = self.recv(8192)
self.received += len(data)
print "received : %d, %d"%(len(data), self.received)
self.f.write(data)
def handle_close(self):
print "closed..."
self.f.close()
self.close()
def main(self, aHost, aPort):
self.connect((aHost, aPort))
if __name__=="__main__":
client=FileReceiveChannel()
host = "localhost"
port = 30002
client.main(host, port)
asyncore.loop()
여기서 recv 메소드는 데이터가 들어온 만큼 받는다. (즉, 버퍼사이즈만큼 데이터가 들어올때까지 기다리지 않는다.)