簡體   English   中英

注冊和選擇套接字究竟是如何工作的?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM