asyncore : Python裡面的非同步Socket

 

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 socket
import asyncore
import threading

MAX_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連線socket
class 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連線的thread
class 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, socket
import threading

#收到data最大長度
MAX_RECV = 4096

#連線server的socket
class 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傳送訊息的thread
class 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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值