web-dev-qa-db-ja.com

Python socket.accept nonblocking?

Pythonのsocket.accept()を非ブロッキングの方法で使用して、それを実行し、新しい接続を取得したかどうかを確認する方法はありますか?私本当にスレッドを使いたくない。ありがとう。

18
pajm

おそらくselect.select()のようなものが必要です( ドキュメント を参照)。 select()に、可読性、書き込み可能性、およびエラー状態を監視するソケットの3つのリストを指定します。サーバーソケットは、新しいクライアントが待機しているときに読み取り可能になります。

select()関数は、ソケットの状態の1つが変更されるまでブロックします。永久にブロックしたくない場合は、オプションの4番目のパラメーターtimeoutを指定できます。

ダムエコーサーバーの例を次に示します。

import select
import socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('', 8888))
server_socket.listen(5)
print "Listening on port 8888"

read_list = [server_socket]
while True:
    readable, writable, errored = select.select(read_list, [], [])
    for s in readable:
        if s is server_socket:
            client_socket, address = server_socket.accept()
            read_list.append(client_socket)
            print "Connection from", address
        else:
            data = s.recv(1024)
            if data:
                s.send(data)
            else:
                s.close()
                read_list.remove(s)

Pythonには、それらをサポートするプラットフォーム用のepollpoll、およびkqueueの実装もあります。これらはselectのより効率的なバージョンです。

31
Nathan Ostgard

ソケットでsetblocking(0)メソッドを呼び出して、非ブロッキングにすることができます。 asyncore module または Twisted のようなフレームワークを調べてください。

2