recv()套接字函数返回长度为0的数据

我有一个应用程序,它在端口号5005上与另一个设备(带有Web服务器的硬件设备)建立了套接字连接。

现在,如果我的硬件设备断开连接,那么我将断开与设备的连接。

  1. 这是否意味着我现在使用的套接字变为无效。

  2. 当发生此断开连接时,是否会收到任何特殊消息,如空字符或其他内容。

  3. 如果我的套接字连接变得无效,那么为什么recv()套接字函数不会抛出和SOCKET_ERROR。 相反,为什么我会收到0长度的数据。

谢谢

recv返回值0表示连接已关闭。

请参阅recv手册页:

这些调用返回接收的字节数,如果发生错误则返回-1。 当对等体执行有序关闭时,返回值将为0。

在回答问题#1时,是套接字现在无效。 您必须创建新的套接字和连接以进行进一步的通信。

编辑

现在正如valdo在下面指出的那样,也有可能有一个半封闭的TCP连接,你不能再接收它,但你可以继续写入套接字,直到你完成数据发送。 有关更多详细信息,请参阅此文章: TCP Half-Close 。 听起来不像你有这种情况。

在回答问题#2时,基本上有两种方法来检测闭合的套接字。 这假设套接字经历了有序关闭,这意味着对等体称为shutdownclose

第一种方法是从套接字读取,在这种情况下,返回值为0.另一种方法是写入套接字,这将导致抛出SIG_PIPE信号,表明管道损坏。

为了避免该信号,您可以设置MSG_NOSIGNAL套接字选项,在这种情况下, send将返回-1并将errnoEPIPE

同意Robert S. Barnes。 除了声称套接字现在“无效”。

它仍然有效。 你可以使用它。 您甚至可以将数据发送给对等方。 你唯一不能做的就是召唤recv

我想你正在使用TCP与你的设备进行通信。

  1. 套接字本身仍然“有效”,但连接丢失了。

  2. 当连接被另一个主机关闭时, recv()的返回值为0(这种断开连接是否优雅无关紧要)

  3. 套接字函数类似于C函数:它们不会抛出,因为它们可以在C程序中使用,其中存在exception。

如果recv返回0,则表示对等体已关闭套接字。

recv不会因为它的C函数而抛出。

如果有错误,recv将返回-1。 在这种情况下,您的应用程序必须检查错误类型。 请注意,返回-1并不意味着对等体已关闭其套接字。

鉴于您正在与Web服务器通信,我假设您正在使用TCP套接字。

回答:

  1. 由于断开连接,套接字不会变得无效; 他们只是进入断开状态。 在它们上调用套接字操作仍然是安全的。

  2. 发生断开连接时,您不会收到任何特殊消息。 如果以阻塞方式调用recv() ,它将在断开连接时返回,并且从调用返回的字节数将与您请求的字节数不匹配。

  3. 对此没有真正的答案 – 它是最初实现套接字API的方式,并且我们坚持使用该实现,因为每个人都实现了Berkley套接字。

纠正现有答案中的许多错误陈述:

  1. 这是否意味着我现在使用的套接字变为无效。

不是。这意味着对等方已关闭连接,或者将其关闭以便从其结束输出。 您的套接字仍然有效。 你可以再次调用recv() ,但你得到的只是另一个零。 您也可以在其上调用send() ,如果对等方只关闭连接输出,则会发送数据。

  1. 发生此断开连接时,是否会收到任何特殊消息,如空字符或其他内容。

不,您从recv()获得零返回值。 这就是它的用途。 它是带外传送的,而不是数据缓冲区。

  1. 如果我的套接字连接变得无效,那么为什么recv()套接字函数不会抛出

因为它是一个C API,并且在C或Unix系统调用中也没有throws

和SOCKET_ERROR。

因为这不是错误。

相反,为什么我会收到0长度的数据。

您没有’收到0长度的数据’。 您收到的返回值为零而不是数据。