基于pythonselect.select模块通信的实例讲解
基于python select.select模塊通信的實例講解
要理解select.select模塊其實主要就是要理解它的參數, 以及其三個返回值。
select()方法接收并監控3個通信列表, 第一個是所有的輸入的data,就是指外部發過來的數據,第2個是監控和接收所有要發出去的data(outgoing data),第3個監控錯誤信息在網上一直在找這個select.select的參數解釋, 但實在是沒有, 哎...自己硬著頭皮分析了一下。?? ?
readable, writable, exceptional = select.select(inputs, outputs, inputs)
第一個參數就是服務器端的socket, 第二個是我們在運行過程中存儲的客戶端的socket, 第三個存儲錯誤信息。
重點是在返回值, 第一個返回的是可讀的list, 第二個存儲的是可寫的list, 第三個存儲的是錯誤信息的list。
這個也不必深究, 看看代碼自己分析下就能有大概理解。
網上所有關于select.select的代碼都是差不多的, 但是有些不能運行, 或是不全。我自己重新寫了一份能運行的程序, 做了很多注釋, 好好看看就能搞懂
服務器端:?? ?
# 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
# 處理要發送的消息
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 監聽, 對input_list 中的服務器端server 進行監聽
? # 一旦調用socket的send, recv函數,將會再次調用此模塊
? readable, writable, exceptional = select.select(inputs, outputs, inputs)
?
? # Handle inputs
? # 循環判斷是否有客戶端連接進來, 當有客戶端連接進來時select 將觸發
? for s in readable:
??? # 判斷當前觸發的是不是服務端對象, 當觸發的對象是服務端對象時,說明有新客戶端連接進來了
??? # 表示有新用戶來連接
??? 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)
????? # 將客戶端對象也加入到監聽的列表中, 當客戶端發送消息時 select 將觸發
????? inputs.append(connection)
?
????? # Give the connection a queue for data we want to send
????? # 為連接的客戶端單獨創建一個消息隊列,用來保存客戶端發送的消息
????? message_queues[connection] = Queue.Queue()
??? else:
????? # 有老用戶發消息, 處理接受
????? # 由于客戶端連接進來時服務端接收客戶端連接請求,將客戶端加入到了監聽列表中(input_list), 客戶端發送消息將觸發
????? # 所以判斷是否是客戶端對象觸發
????? data = s.recv(1024)
????? # 客戶端未斷開
????? if data != '':
??????? # A readable client socket has data
??????? print ('received "%s" from %s' % (data, s.getpeername()))
??????? # 將收到的消息放入到相對應的socket客戶端的消息隊列中
??????? message_queues[s].put(data)
??????? # Add output channel for response
??????? # 將需要進行回復操作socket放到output 列表中, 讓select監聽
??????? if s not in outputs:
????????? outputs.append(s)
????? else:
??????? # 客戶端斷開了連接, 將客戶端的監聽從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
轉載于:https://www.cnblogs.com/amengduo/p/9586311.html
總結
以上是生活随笔為你收集整理的基于pythonselect.select模块通信的实例讲解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 股票红色代表什么
- 下一篇: Python 过滤字母和数字