MFC裡面有個Class叫做CAsyncsocket, 它是用實作非同步的socket.
在實際的應用裡面, 一個應用程式很少會固定等待socket連線, 或是傳送資料, 通常都是在突然的情況下一個socket要進行連線, 或是要傳送資料. 所以非同步的socket的好處就在這裡, 你可以指定在socket發生連線或是傳送資料的時候進行某個動作, 而CAsyncsocket就是把這樣的非同步行為包成一個class讓我們只要繼承它就能達到這樣的效果.
而在Python裡面也有個 非同步的module叫做asyncore. 我們實作的socket只要繼承asyncore.dispatcher就能進行非同步的 socket運作.
下面就有Client和Server的範例code, 主要用途在於Client能連上Server, 然後Client和Server之間就能進行非同步的溝通, Client可以輸入訊息給Server, Server也能輸入訊息給Client.
Server 程式 :
# -*- coding: cp950 -*-import socketimport asyncoreimport threadingMAX_RECV = 4096#負責接受client socket連線class AgentServer(asyncore.dispatcher): def __init__(self, port): #asyncore.dispatcher的constructor asyncore.dispatcher.__init__(self) #client socket self.clientSocket = None #server port self.port = port #建立等待的socket self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.bind(('', self.port)) self.listen(5) def handle_accept(self): #接受client socket的連線 self.clientSocket, address = self.accept() print 'New client from : ' + address[0] #將和client連線的socket加上一些功能 (自訂socket) self.clientSocket = ClientAgent(self.clientSocket)#自訂的client連線socketclass ClientAgent(asyncore.dispatcher): def __init__(self, socket): asyncore.dispatcher.__init__(self, socket) #要送出的data self.SendData = "" #從client收到的data def handle_read(self): self.RecvData = self.recv(MAX_RECV) if len(self.RecvData) > 0: print "recv : " + self.RecvData #送出data到client def handle_write(self): send_byte = self.send(self.SendData) #一次可能不會全部送完(一次最多送出512 bytes ?) if send_byte > 0: send_out = self.SendData[:send_byte] self.SendData = self.SendData[send_byte:] self.handle_write() else: print "send all!!" self.SendData = "" #不自動執行handle_write def writable(self): return False def handle_close(self): print "close connection : " + self.getpeername()[0] self.close()#產生等待client連線的threadclass listen_client_thread(threading.Thread): def __init__(self,port): self.agentServer = AgentServer(port) threading.Thread.__init__ ( self ) def run(self): print "Listen Client ..." asyncore.loop()#產生處理輸入的thread class input_thread(threading.Thread): def __init__(self,listen_thread): self.listen_thread = listen_thread threading.Thread.__init__ ( self ) def run(self): while 1: send_data = raw_input() self.listen_thread.agentServer.clientSocket.SendData = send_data self.listen_thread.agentServer.clientSocket.handle_write()if __name__ == "__main__": #產生等待client連線的thread listen_thread = listen_client_thread(111) listen_thread.start() #產生處理輸入的thread input_thread(listen_thread).start()Client 程式 :# -*- coding: cp950 -*-import asyncore, socketimport threading#收到data最大長度MAX_RECV = 4096#連線server的socketclass client(asyncore.dispatcher): def __init__(self, host, port): asyncore.dispatcher.__init__(self) self.SendData = "" self.RecvData = "" #和server建立連線 self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.connect( (host, port) ) def handle_connect(self): print 'connect!!' def handle_close(self): print "disconnection : " + self.getpeername()[0] self.close() #收到的data def handle_read(self): self.RecvData = self.recv(MAX_RECV) if len(self.RecvData) > 0: print "recv : " + self.RecvData #送出data def handle_write(self): send_byte = self.send(self.SendData) if send_byte > 0: send_out = self.SendData[:send_byte] self.SendData = self.SendData[send_byte:] print "send : " + send_out self.handle_write() else: print "send all!!" self.SendData = "" #自動偵測送出永遠失敗 def writable(self): return False #等待server傳送訊息的threadclass send_server_thread(threading.Thread): def __init__(self,host,port): self.client = client(host, port) threading.Thread.__init__ ( self ) def run(self): try: asyncore.loop() except: pass#等待user input的thread class input_thread(threading.Thread): def __init__(self,client_thread): self.client_thread = client_thread threading.Thread.__init__ ( self ) def run(self): while 1: send_data = raw_input() self.client_thread.client.SendData = send_data self.client_thread.client.handle_write()#主程式if __name__ == "__main__": #建立和server連線, 並且等待溝通 client_thread = send_server_thread("localhost",111) client_thread.start() #等待user input input_thread(client_thread).start()