基于pythonselect.select模块通信的实例讲解
基于python select.select模塊通信的實(shí)例講解
要理解select.select模塊其實(shí)主要就是要理解它的參數(shù), 以及其三個(gè)返回值。
select()方法接收并監(jiān)控3個(gè)通信列表, 第一個(gè)是所有的輸入的data,就是指外部發(fā)過來的數(shù)據(jù),第2個(gè)是監(jiān)控和接收所有要發(fā)出去的data(outgoing data),第3個(gè)監(jiān)控錯(cuò)誤信息在網(wǎng)上一直在找這個(gè)select.select的參數(shù)解釋, 但實(shí)在是沒有, 哎...自己硬著頭皮分析了一下。?? ?
readable, writable, exceptional = select.select(inputs, outputs, inputs)
第一個(gè)參數(shù)就是服務(wù)器端的socket, 第二個(gè)是我們?cè)谶\(yùn)行過程中存儲(chǔ)的客戶端的socket, 第三個(gè)存儲(chǔ)錯(cuò)誤信息。
重點(diǎn)是在返回值, 第一個(gè)返回的是可讀的list, 第二個(gè)存儲(chǔ)的是可寫的list, 第三個(gè)存儲(chǔ)的是錯(cuò)誤信息的list。
這個(gè)也不必深究, 看看代碼自己分析下就能有大概理解。
網(wǎng)上所有關(guān)于select.select的代碼都是差不多的, 但是有些不能運(yùn)行, 或是不全。我自己重新寫了一份能運(yùn)行的程序, 做了很多注釋, 好好看看就能搞懂
服務(wù)器端:?? ?
# coding: utf-8
import select
import socket
import Queue
from time import sleep
?
?
# Create a TCP/IP
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(False)
?
# Bind the socket to the port
server_address = ('localhost', 8090)
print ('starting up on %s port %s' % server_address)
server.bind(server_address)
?
# Listen for incoming connections
server.listen(5)
?
# Sockets from which we expect to read
inputs = [server]
?
# Sockets to which we expect to write
# 處理要發(fā)送的消息
outputs = []
?
# Outgoing message queues (socket: Queue)
message_queues = {}
?
while inputs:
? # Wait for at least one of the sockets to be ready for processing
? print ('waiting for the next event')
? # 開始select 監(jiān)聽, 對(duì)input_list 中的服務(wù)器端server 進(jìn)行監(jiān)聽
? # 一旦調(diào)用socket的send, recv函數(shù),將會(huì)再次調(diào)用此模塊
? readable, writable, exceptional = select.select(inputs, outputs, inputs)
?
? # Handle inputs
? # 循環(huán)判斷是否有客戶端連接進(jìn)來, 當(dāng)有客戶端連接進(jìn)來時(shí)select 將觸發(fā)
? for s in readable:
??? # 判斷當(dāng)前觸發(fā)的是不是服務(wù)端對(duì)象, 當(dāng)觸發(fā)的對(duì)象是服務(wù)端對(duì)象時(shí),說明有新客戶端連接進(jìn)來了
??? # 表示有新用戶來連接
??? if s is server:
????? # A "readable" socket is ready to accept a connection
????? connection, client_address = s.accept()
????? print ('connection from', client_address)
????? # this is connection not server
????? connection.setblocking(0)
????? # 將客戶端對(duì)象也加入到監(jiān)聽的列表中, 當(dāng)客戶端發(fā)送消息時(shí) select 將觸發(fā)
????? inputs.append(connection)
?
????? # Give the connection a queue for data we want to send
????? # 為連接的客戶端單獨(dú)創(chuàng)建一個(gè)消息隊(duì)列,用來保存客戶端發(fā)送的消息
????? message_queues[connection] = Queue.Queue()
??? else:
????? # 有老用戶發(fā)消息, 處理接受
????? # 由于客戶端連接進(jìn)來時(shí)服務(wù)端接收客戶端連接請(qǐng)求,將客戶端加入到了監(jiān)聽列表中(input_list), 客戶端發(fā)送消息將觸發(fā)
????? # 所以判斷是否是客戶端對(duì)象觸發(fā)
????? data = s.recv(1024)
????? # 客戶端未斷開
????? if data != '':
??????? # A readable client socket has data
??????? print ('received "%s" from %s' % (data, s.getpeername()))
??????? # 將收到的消息放入到相對(duì)應(yīng)的socket客戶端的消息隊(duì)列中
??????? message_queues[s].put(data)
??????? # Add output channel for response
??????? # 將需要進(jìn)行回復(fù)操作socket放到output 列表中, 讓select監(jiān)聽
??????? if s not in outputs:
????????? outputs.append(s)
????? else:
??????? # 客戶端斷開了連接, 將客戶端的監(jiān)聽從input列表中移除
??????? # Interpret empty result as closed connection
??????? print ('closing', client_address)
??????? # Stop listening for input on the connection
??????? if s in outputs:
????????? outputs.remove(s)
??????? inputs.remove(s)
??????? s.close()
?
??????? # Remove message queue
轉(zhuǎn)載于:https://www.cnblogs.com/amengduo/p/9586311.html
總結(jié)
以上是生活随笔為你收集整理的基于pythonselect.select模块通信的实例讲解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 股票红色代表什么
- 下一篇: 氢能源概念股有哪些值得关注 投资者们可以