這篇文章主要介紹了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 ctimeimport selectimport sysHOST = ''PORT = 21567BUFSIZ = 1024ADDR = (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 ctimeimport selectimport sysHOST = 'localhost'PORT = 21567BUFSIZ = 1024ADDR = (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': breaktcpCliSock.close()
目前為止,已經實現了一對一全雙工系統聊天通訊啦。
下面當然要思考下,如何?多對多通訊呢?
我們知道,一個伺服器可以為多個用戶端服務,即,伺服器與用戶端本身有著一對多的關係,那麼,我們是否可以利用伺服器作為中間人,用來傳達資訊,從而實現多對多通訊呢?
舉個例子,A想要和B通訊,則A將資訊發送給伺服器,然後再通過伺服器轉寄給B。按照這個思路去寫,完成多對多通訊應該是可以的,有興趣的可以嘗試一下。