[英]How exactly does registering and selecting a socket work?
我正在使用 Python 學習一些網絡。 雖然我找到了很多代碼示例,但我沒有找到對某些代碼的任何解釋。 在選擇器模塊中似乎有兩個重要的功能,寄存器和 select。 我找不到關於他們到底做了什么的很好的解釋,所以我希望這里有人能提供幫助。
As an example I played around a bit with some sample code from the python documentation at https://docs.python.org/3/library/selectors.html . 此代碼示例以
sel.register(sock, selectors.EVENT_READ, accept)
while True:
events = sel.select()
for key, mask in events:
callback = key.data
callback(key.fileobj, mask)
其中“accept”是代碼中其他地方定義的 function,“sel”是選擇器。 我注意到一開始 select() 調用會阻塞代碼,直到客戶端建立連接。 但它究竟返回了什么? 從一些實驗來看,它似乎返回一個列表,其中包含每個已更新的已注冊套接字的項目。 但是什么是“掩碼”變量? 在 python 文檔中,它說它是“此文件對象上准備好的事件的位掩碼” ,但我不知道這意味着什么,在我的實驗中它似乎只是值 1。
此外,當我將 for 循環替換為“print(events)”時,我注意到一旦使用了套接字,代碼就不再每次都在 sel.select() 處等待。 為什么是這樣?
注冊套接字時,我不明白 data 參數。 文檔只是說它是一個“不透明對象” ,默認情況下它是None 。 這里似乎是在使用套接字時應該調用的 function,但總是這樣嗎? 為了清楚起見, selectors.EVENT_READ 參數表明套接字只能接收信息,不能發送信息,對吧?
在此先感謝您的幫助!
我注意到一開始 select() 調用會阻塞代碼,直到客戶端建立連接。
更准確地說,它會阻塞,直到一個或多個已注冊的 sockets 匹配其已注冊的事件之一。 因此,在您的示例中, select()
將無限期地阻塞(因為您沒有為timeout
參數指定值),直到sock
報告EVENT_READ
事件已准備好。
但它究竟返回了什么? 從一些實驗來看,它似乎返回一個列表,其中包含每個已更新的已注冊套接字的項目。 但是什么是“掩碼”變量?
這在您鏈接到的同一文檔中得到了回答:
這將返回一個
(key, events)
元組列表,每個准備好的文件 object 一個。
key
是對應准備好的文件 object 的SelectorKey實例。events
是此文件 object 上准備好的事件的位掩碼。
在 python 文檔中它說它是“在這個文件對象上准備好的事件的位掩碼”,但我不知道這意味着什么
您可以為一個套接字注冊多個事件。 報告的mask
將告訴您哪些事件實際上已准備好。
在我的實驗中,它似乎只是值 1。
這是EVENT_READ
的數值。 這是您獲得的唯一價值,因為這是您注冊的唯一事件。 但是您可以注冊其他事件,例如EVENT_WRITE
。
此外,當我將 for 循環替換為“print(events)”時,我注意到一旦使用了套接字,代碼就不再每次都在 sel.select() 處等待。 為什么是這樣?
因為您不再調用您的accept()
function 來從套接字讀取數據。 只要套接字有等待讀取的待處理數據,套接字就會保留在可讀的 state 中。 因此,您的select()
將繼續報告EVENT_READ
已為套接字做好准備,直到其所有未決數據已被讀取。
注冊套接字時,我不明白 data 參數。
它是你想要的任何東西。 您可以將所需的任何自定義數據與事件注冊相關聯,然后select()
將在每次報告事件時將該數據返回給您。
文檔只是說它是一個“不透明對象”,默認情況下它是 None 。 這里似乎是在使用套接字時應該調用的 function,但總是這樣嗎?
不,它可以是你需要的任何東西。
為了清楚起見, selectors.EVENT_READ 參數表明套接字只能接收信息,不能發送信息,對吧?
不。這意味着您有興趣僅在套接字位於可讀的 state 時收到通知。 您始終可以寫入套接字,至少在對其調用shutdown(SHUT_WR)
或close()
之前。 對於非阻塞套接字,如果send()
阻塞(因為接收器的緩沖區已滿),它可能會失敗,在這種情況下,您必須等待套接字上的EVENT_WRITE
准備好(接收器已准備好接收更多數據) 在您可以再次在該套接字上發送數據之前。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.