簡體   English   中英

Python的select模塊中的select()函數如何正常工作?

[英]How does the select() function in the select module of Python exactly work?

我正在用Python編寫面向網絡的應用程序。 我之前曾使用過阻塞套接字,但在更好地理解了需求和概念后,我想使用非阻塞套接字編寫應用程序,從而編寫一個事件驅動的服務器。

據我所知,Python中select模塊中的函數用於方便地查看哪個socket對我們感興趣等等。 為此,我基本上試圖翻閱事件驅動服務器的幾個例子,我遇到過這個:

"""
An echo server that uses select to handle multiple clients at a time.
Entering any line of input at the terminal will exit the server.
"""

import select
import socket
import sys

host = ''
port = 50000
backlog = 5
size = 1024
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host,port))
server.listen(backlog)
input = [server,sys.stdin]
running = 1
while running:
    inputready,outputready,exceptready = select.select(input,[],[])

    for s in inputready:

        if s == server:
            # handle the server socket
            client, address = server.accept()
            input.append(client)

        elif s == sys.stdin:
            # handle standard input
            junk = sys.stdin.readline()
            running = 0

        else:
            # handle all other sockets
            data = s.recv(size)
            if data:
                s.send(data)
            else:
                s.close()
                input.remove(s)
server.close() 

我似乎不理解的部分如下:

在代碼片段inputready,outputready,exceptready = select.select(input,[],[]) ,我相信select()函數返回三個可能為輸入,輸出和異常條件的可等對象的空列表。 因此, select()函數的第一個參數是包含服務器套接字和stdin的列表是有道理的。 但是,我面臨混淆的else是代碼的else塊。

由於我們用於循環輸入插槽列表,因此很明顯select()函數將選擇一個可以讀取的客戶端套接字。 但是,在我們使用recv()讀取數據並發現套接字實際已發送數據之后,我們希望將其回送給客戶端。 我的問題是我們如何寫入這個套接字而不將它添加到作為select()函數調用的第二個參數傳遞的列表中? 意思是,如何直接在新套接字上調用send()而不用select()作為可寫套接字“注冊”它?

另外,為什么我們只在准備好讀取的套接字上循環(在這種情況下是inputready)? 是否有必要循環甚至輸出已完成列表以查看哪些套接字已准備好寫入? 顯然,我在這里遺漏了一些東西。

如果有人能夠以更詳細的方式解釋select()函數的工作或指向好的文檔,那也會非常有用。

謝謝。

可能代碼片段只是一個簡單的例子,因此並非詳盡無遺。 您可以自由地在每個插槽中進行寫入和讀取,如果select沒有告訴您它們已准備就緒。 但是,當然,如果你這樣做,你不能確定你的send()不會阻止。 所以,是的,最佳做法是依賴select也進行編寫操作。 還有許多其他功能具有相似的目的,在許多情況下它們比選擇(例如epoll )更好,但它們並非在所有平台上都可用。 有關select,epoll和其他函數的信息可以在Linux手冊頁中找到。

然而在python中有許多很好的庫用於處理許多連接,其中一些是: Twistedgevent

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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