這篇文章主要介紹了Python網路程式設計使用select實作socket全雙工非同步通訊功能,在這裡分享給大家,有需要的朋友可以參考下
本文實例講述了Python網路程式設計使用select實作socket全雙工非同步通訊功能。分享給大家供大家參考,具體如下:
在前面一篇《Python網絡編程之TCP套接字簡單用法》中,我們實現了tcp客戶端與伺服器的通信,但是功能十分局限,發送訊息與接收訊息不能同時進行。
接下來我將透過select這個模組,來實現全雙工通訊(隨時可以接收訊息以及發送訊息),當然,用多線程也可以完成,這是後話。
那麼,select為何?
select -在單執行緒網路服務中器程式中,管理多個套接字連接
select的原型為(rlist,wlist,xlist[,timeout ]),其中rlist是等待讀取的對象,wlist是等待寫入的對象,xlist是等待異常的對象,最後一個是可選對象,指定等待的時間,單位是s.
select()
方法的回傳值是準備好的物件的三元組,若在timeout的時間內,沒有物件準備好,那麼傳回值將會是空的清單。
它採用的是輪詢的方式來實現非同步通訊的。
在下面程式中,目前主要支援1對1通信,當雙方任何一方發送字串‘88'時,表示結束通信。
下面我們來看看具體實作:
首先是伺服器。
#!/usr/bin/python 'test TCP server' from socket import * from time import ctime import select import sys HOST = '' PORT = 21567 BUFSIZ = 1024 ADDR = (HOST, PORT) tcpSerSock = socket(AF_INET, SOCK_STREAM) tcpSerSock.bind(ADDR) tcpSerSock.listen(5) input = [tcpSerSock, sys.stdin] #input是一个列表,初始有欢迎套接字以及标准输入 while True: print 'waiting for connection...' tcpCliSock, addr = tcpSerSock.accept() print '...connected from:',addr input.append(tcpCliSock) #将服务套接字加入到input列表中 while True: readyInput,readyOutput,readyException = select.select(input,[],[]) #从input中选择,轮流处理client的请求连接(tcpSerSock),client发送来的消息(tcpCliSock),及服务器端的发送消息(stdin) for indata in readyInput: if indata==tcpCliSock: #处理client发送来的消息 data = tcpCliSock.recv(BUFSIZ) print data if data=='88': input.remove(tcpCliSock) break else: #处理服务器端的发送消息 data = raw_input('>') if data=='88': tcpCliSock.send('%s' %(data)) input.remove(tcpCliSock) break tcpCliSock.send('[%s] %s' %(ctime(), data)) if data=='88': break tcpCliSock.close() tcpSerSock.close()
以下是客戶端的程式碼,非常類似,只是與伺服器相比不需要處理請求資訊而已。
#!/usr/bin/python 'test tcp client' from socket import * from time import ctime import select import sys HOST = 'localhost' PORT = 21567 BUFSIZ = 1024 ADDR = (HOST, PORT) tcpCliSock = socket(AF_INET, SOCK_STREAM) tcpCliSock.connect(ADDR) input = [tcpCliSock,sys.stdin] while True: readyInput,readyOutput,readyException = select.select(input,[],[]) for indata in readyInput: if indata==tcpCliSock: data = tcpCliSock.recv(BUFSIZ) print data if data=='88': break else: data = raw_input('>') if data=='88': tcpCliSock.send('%s' %(data)) break tcpCliSock.send('[%s] %s' %(ctime(), data)) if data=='88': break tcpCliSock.close()
目前為止,已經實現了一對一全雙工聊天通訊啦。
下面當然要思考下,如何實現多對多通訊呢?
我們知道,一個伺服器可以為多個客戶端服務,即,伺服器與客戶端本身有著一對多的關係,那麼,我們是否可以利用伺服器作為中間人,用來傳達訊息,從而實現多對多通信呢?
舉個例子,A想要和B通信,則A將訊息傳送給伺服器,然後再透過伺服器轉發給B。照這個思路去寫,完成多對多通訊應該是可以的,有興趣的可以試試看。
相關推薦:
以上是Python網路程式設計之使用select實作socket全雙工非同步通訊功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!