web-dev-qa-db-ja.com

Pythonのソケットrecvメソッドにタイムアウトを設定する方法は?

Pythonのソケットrecvメソッドにタイムアウトを設定する必要があります。どうやるか?

93
Thoreller

典型的なアプローチは、 select() を使用して、データが利用可能になるか、タイムアウトが発生するまで待機することです。データが実際に利用可能な場合にのみ、recv()を呼び出します。安全にするために、recv()が無期限にブロックされないように、ソケットを非ブロックモードに設定します。 select()は、一度に複数のソケットで待機するためにも使用できます。

import select

mysocket.setblocking(0)

ready = select.select([mysocket], [], [], timeout_in_seconds)
if ready[0]:
    data = mysocket.recv(4096)

開いているファイル記述子がたくさんある場合は、 poll()select()のより効率的な代替手段です。

別のオプションは、socket.settimeout()を使用してソケットのすべての操作のタイムアウトを設定することですが、別の答えでその解決策を明示的に拒否したことがわかります。

111

socket.settimeout() があります

50
nosklo

前述のように、 select.select()socket.settimeout() の両方が機能します。

必要に応じてsettimeoutを2回呼び出す必要がある場合があることに注意してください。

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("",0))
sock.listen(1)
# accept can throw socket.timeout
sock.settimeout(5.0)
conn, addr = sock.accept()

# recv can throw socket.timeout
conn.settimeout(5.0)
conn.recv(1024)
25
ubershmekel

応答を受信する前にタイムアウトを設定し、応答を受信した後にタイムアウトをNoneに戻すことができます。

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sock.settimeout(5.0)
data = sock.recv(1024)
sock.settimeout(None)
11
noriko

サーバー側を実装する場合、探しているタイムアウトは、プライマリソケットではなく接続ソケットのタイムアウトです。つまり、接続ソケットオブジェクトには別のタイムアウトがあります。これは、socket.accept()メソッドの出力です。したがって:

sock.listen(1)
connection, client_address = sock.accept()
connection.settimeout(5)    # This is the one that affects recv() method.
connection.gettimeout()     # This should result 5
sock.gettimeout()           # This outputs None when not set previously, if I remember correctly.

クライアント側を実装する場合、それは簡単です。

sock.connect(server_address)
sock.settimeout(3)
4
V123

秒数を表す整数引数を受け入れるsocket.settimeout()を使用できます。たとえば、socket.settimeout(1)はタイムアウトを1秒に設定します

2
Brian Zheng

前の返信で述べたように、次のようなものを使用できます:.settimeout()例:

import socket

s = socket.socket()

s.settimeout(1) # Sets the socket to timeout after 1 second of no activity

Host, port = "somehost", 4444
s.connect((Host, port))

s.send("Hello World!\r\n")

try:
    rec = s.recv(100) # try to receive 100 bytes
except socket.timeout: # fail after 1 second of no activity
    print("Didn't receive data! [Timeout]")
finally:
    s.close()

これがお役に立てば幸いです!!

2
petrexxy

試してみて、基礎となるCを使用します。

timeval = struct.pack('ll', 2, 100)
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeval)
1