recv()套接字函数返回长度为0的数据
我有一个应用程序,它在端口号5005上与另一个设备(带有Web服务器的硬件设备)建立了套接字连接。
现在,如果我的硬件设备断开连接,那么我将断开与设备的连接。
-
这是否意味着我现在使用的套接字变为无效。
-
当发生此断开连接时,是否会收到任何特殊消息,如空字符或其他内容。
- 如果我的套接字连接变得无效,那么为什么recv()套接字函数不会抛出和SOCKET_ERROR。 相反,为什么我会收到0长度的数据。
谢谢
当recv
返回值0表示连接已关闭。
请参阅recv
手册页:
这些调用返回接收的字节数,如果发生错误则返回-1。 当对等体执行有序关闭时,返回值将为0。
在回答问题#1时,是套接字现在无效。 您必须创建新的套接字和连接以进行进一步的通信。
编辑
现在正如valdo在下面指出的那样,也有可能有一个半封闭的TCP连接,你不能再接收它,但你可以继续写入套接字,直到你完成数据发送。 有关更多详细信息,请参阅此文章: TCP Half-Close 。 听起来不像你有这种情况。
在回答问题#2时,基本上有两种方法来检测闭合的套接字。 这假设套接字经历了有序关闭,这意味着对等体称为shutdown
或close
。
第一种方法是从套接字读取,在这种情况下,返回值为0.另一种方法是写入套接字,这将导致抛出SIG_PIPE信号,表明管道损坏。
为了避免该信号,您可以设置MSG_NOSIGNAL
套接字选项,在这种情况下, send
将返回-1并将errno
为EPIPE
。
同意Robert S. Barnes。 除了声称套接字现在“无效”。
它仍然有效。 你可以使用它。 您甚至可以将数据发送给对等方。 你唯一不能做的就是召唤recv
。
我想你正在使用TCP与你的设备进行通信。
-
套接字本身仍然“有效”,但连接丢失了。
-
当连接被另一个主机关闭时,
recv()
的返回值为0(这种断开连接是否优雅无关紧要) -
套接字函数类似于
C
函数:它们不会抛出,因为它们可以在C
程序中使用,其中不存在exception。
如果recv返回0,则表示对等体已关闭套接字。
recv不会因为它的C函数而抛出。
如果有错误,recv将返回-1。 在这种情况下,您的应用程序必须检查错误类型。 请注意,返回-1并不意味着对等体已关闭其套接字。
鉴于您正在与Web服务器通信,我假设您正在使用TCP套接字。
回答:
-
由于断开连接,套接字不会变得无效; 他们只是进入断开状态。 在它们上调用套接字操作仍然是安全的。
-
发生断开连接时,您不会收到任何特殊消息。 如果以阻塞方式调用
recv()
,它将在断开连接时返回,并且从调用返回的字节数将与您请求的字节数不匹配。 -
对此没有真正的答案 – 它是最初实现套接字API的方式,并且我们坚持使用该实现,因为每个人都实现了Berkley套接字。
纠正现有答案中的许多错误陈述:
- 这是否意味着我现在使用的套接字变为无效。
不是。这意味着对等方已关闭连接,或者将其关闭以便从其结束输出。 您的套接字仍然有效。 你可以再次调用recv()
,但你得到的只是另一个零。 您也可以在其上调用send()
,如果对等方只关闭连接输出,则会发送数据。
- 发生此断开连接时,是否会收到任何特殊消息,如空字符或其他内容。
不,您从recv()
获得零返回值。 这就是它的用途。 它是带外传送的,而不是数据缓冲区。
- 如果我的套接字连接变得无效,那么为什么
recv()
套接字函数不会抛出
因为它是一个C API,并且在C或Unix系统调用中也没有throws
。
和SOCKET_ERROR。
因为这不是错误。
相反,为什么我会收到0长度的数据。
您没有’收到0长度的数据’。 您收到的返回值为零而不是数据。