基本上,我在几个地方读到过socket.recv()
将返回它所能读取的任何内容,或者一个空字符串表示另一方已经关闭(官方文档甚至没有提到它在连接关闭时返回的内容。。。太好了!对于阻塞套接字来说,这一切都很好,因为我们知道recv()
只在实际有东西要接收时返回,所以当它返回空字符串时,它必须表示另一方已经关闭了连接,对吧?
好吧,好吧,但是如果我的插座没有阻塞怎么办??我搜了一下(也许还不够,谁知道?)无法知道对方何时使用非阻塞套接字关闭了连接。似乎没有任何方法或属性告诉我们这一点,将recv()
的返回值与空字符串进行比较似乎完全没有用处。。。只是我有这个问题吗?
作为一个简单的例子,假设我的套接字的超时设置为1.2342342秒(无论您喜欢哪个非负数),我调用socket.recv(1024)
,但另一方在1.2342342秒期间不发送任何内容。调用recv()
将返回一个空字符串,我不知道连接是否仍处于正常状态。。。
当您使用
recv
与select
连接时,如果套接字已准备好读取,但没有要读取的数据,则表示客户端已关闭连接。下面是一些处理此问题的代码,还要注意在while循环中第二次调用
recv
时引发的异常。如果没有任何内容可供读取,则将引发此异常,但这并不意味着客户端已关闭连接:以及接收数据的函数:
很简单:如果
recv()
返回0个字节;you will not receive any more data on this connection. Ever.您仍然可以发送。这意味着,如果没有可用的数据,但连接仍处于活动状态(另一端可能发送),则非阻塞套接字必须引发异常(它可能依赖于系统)。
对于没有可用数据的非阻塞套接字,recv将抛出socket.error异常,该异常的值将具有EAGAIN或ewooldblock的errno。示例:
当您通过使用^{} 或^{} 超时来启用非阻塞行为时,情况略有不同。在这种情况下,会引发socket.error,但在超时的情况下,伴随的异常值始终是设置为“超时”的字符串。所以,要处理这个案子,你可以:
如注释所示,这也是一个更可移植的解决方案,因为它不依赖于操作系统特定的功能来将套接字置于非阻塞模式。
有关详细信息,请参见recv(2)和python socket。
相关问题 更多 >
编程相关推荐