在gevent.socket中读取超时

时间:2014-01-11 16:18:42

标签: sockets timeout gevent

我可以使用gevent.socket.create_connection

打开连接
self.socket = socket.create_connection(self.address,timeout=timeout)
...
payload = ""
while len(payload) < length:
    b = self.socket.recv(length - len(payload))
    payload += b
...
print payload

但是有些时候recv失败并引发socket.timeout例外。

知道什么可能导致这样的例外吗?并且只是循环直到recv返回字符串工作,即,这仍然允许检测定期断开连接吗?

1 个答案:

答案 0 :(得分:0)

我只能假设达到了超时并且它引发了一个超时异常,我觉得很奇怪,因为我无法重现,如果我创建一个套接字并让它超时,连接就会关闭。这是一个引用来自docs的文档gevent.socket.create_connection

  

传递可选的超时参数将设置超时   尝试连接之前的套接字实例。如果未提供超时,则使用getdefaulttimeout()返回的全局默认超时设置。

getdefaulttimeout()默认为None,这意味着套接字没有超时。

socket.recv()返回空字符串之前,您应该始终循环直到收到所有数据。这表示连接已关闭(无论出于何种原因)。这适用于gevent套接字。

我引用socket howto

  

当recv返回0字节时,表示另一方已关闭(或正在关闭)连接。您将不会再收到有关此连接的数据。如初。

你的循环看起来应该像处理空字符串一样:

self.socket = gevent.socket.create_connection(self.address) # if timeout is necessary, make sure you add a high enough value.

payload = ""
while len(payload) < length:
    b = self.socket.recv(length - len(payload))
    if not b:
        break # or return, or raise an exception.
    payload += b