I need to set timeout on python's socket recv method. How to do it?
我需要在python的socket recv方法上设置超时。如何去做?
6 个解决方案
#1
90
The typical approach is to use select() to wait until data is available or until the timeout occurs. Only call recv()
when data is actually available. To be safe, we also set the socket to non-blocking mode to guarantee that recv()
will never block indefinitely. select()
can also be used to wait on more than one socket at a time.
典型的方法是使用select()来等待数据可用或超时。只有当数据可用时才调用recv()。为了安全起见,我们还将套接字设置为非阻塞模式,以确保recv()永远不会无限期地阻塞。select()也可以用于一次等待多个套接字。
import select
mysocket.setblocking(0)
ready = select.select([mysocket], [], [], timeout_in_seconds)
if ready[0]:
data = mysocket.recv(4096)
If you have a lot of open file descriptors, poll() is a more efficient alternative to select()
.
如果您有很多打开的文件描述符,那么poll()是选择()的更有效的替代方法。
Another option is to set a timeout for all operations on the socket using socket.settimeout()
, but I see that you've explicitly rejected that solution in another answer.
另一个选项是使用socket.com .settimeout()为套接字上的所有操作设置一个超时,但是我看到您在另一个答案中明确地拒绝了这个解决方案。
#3
20
As mentioned both select.select()
and socket.settimeout()
will work.
如前所述,select()和socket.settimeout()都可以工作。
Note you might need to call settimeout
twice for your needs, e.g.
注意你可能需要两次调用settimeout来满足你的需要。
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 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)
#4
9
You could set timeout before receiving the response and after having received the response set it back to None:
您可以在接收响应之前设置超时,并在接收到响应后将其设置为None:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5.0)
data = sock.recv(1024)
sock.settimeout(None)
#5
1
The timeout that you are looking for is the connection socket's timeout not the primary socket's, if you implement the server side. In other words, there is another timeout for the connection socket object, which is the output of socket.accept()
method. Therefore:
如果您实现了服务器端,那么您正在寻找的超时是连接套接字的超时,而不是主套接字的超时。换句话说,连接套接字对象有另一个超时,即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.
If you implement the client side, it would be simple.
如果实现了客户端,就会很简单。
sock.connect(server_address)
sock.settimeout(3)
#6
-1
try this it uses the underlying C.
试试这个,它使用了底层的C。
timeval = struct.pack('ll', 2, 100)
s.setsockopt(socket.SOL_SOCKET,SO_RCVTIMEO, timeval)
#1
90
The typical approach is to use select() to wait until data is available or until the timeout occurs. Only call recv()
when data is actually available. To be safe, we also set the socket to non-blocking mode to guarantee that recv()
will never block indefinitely. select()
can also be used to wait on more than one socket at a time.
典型的方法是使用select()来等待数据可用或超时。只有当数据可用时才调用recv()。为了安全起见,我们还将套接字设置为非阻塞模式,以确保recv()永远不会无限期地阻塞。select()也可以用于一次等待多个套接字。
import select
mysocket.setblocking(0)
ready = select.select([mysocket], [], [], timeout_in_seconds)
if ready[0]:
data = mysocket.recv(4096)
If you have a lot of open file descriptors, poll() is a more efficient alternative to select()
.
如果您有很多打开的文件描述符,那么poll()是选择()的更有效的替代方法。
Another option is to set a timeout for all operations on the socket using socket.settimeout()
, but I see that you've explicitly rejected that solution in another answer.
另一个选项是使用socket.com .settimeout()为套接字上的所有操作设置一个超时,但是我看到您在另一个答案中明确地拒绝了这个解决方案。
#2
#3
20
As mentioned both select.select()
and socket.settimeout()
will work.
如前所述,select()和socket.settimeout()都可以工作。
Note you might need to call settimeout
twice for your needs, e.g.
注意你可能需要两次调用settimeout来满足你的需要。
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 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)
#4
9
You could set timeout before receiving the response and after having received the response set it back to None:
您可以在接收响应之前设置超时,并在接收到响应后将其设置为None:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5.0)
data = sock.recv(1024)
sock.settimeout(None)
#5
1
The timeout that you are looking for is the connection socket's timeout not the primary socket's, if you implement the server side. In other words, there is another timeout for the connection socket object, which is the output of socket.accept()
method. Therefore:
如果您实现了服务器端,那么您正在寻找的超时是连接套接字的超时,而不是主套接字的超时。换句话说,连接套接字对象有另一个超时,即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.
If you implement the client side, it would be simple.
如果实现了客户端,就会很简单。
sock.connect(server_address)
sock.settimeout(3)
#6
-1
try this it uses the underlying C.
试试这个,它使用了底层的C。
timeval = struct.pack('ll', 2, 100)
s.setsockopt(socket.SOL_SOCKET,SO_RCVTIMEO, timeval)