我有一个应用程序,它在端口号5005上与另一个设备(带有Web服务器的硬件设备)建立了套接字连接。
现在,如果我的硬件设备断开连接,那么我将断开与设备的连接。
这是否意味着我是套接字 使用到现在变得无效。
我是否收到任何特殊消息 null字符或什么时候 这种脱节发生了。
由于
答案 0 :(得分:35)
当recv
返回值0表示连接已关闭时。
这些调用返回接收的字节数,如果发生错误则返回-1 发生了。 当对等体有序执行时,返回值将为0 关机。
在回答问题#1时,是的套接字现在无效。您必须创建新的套接字和连接以进行进一步的通信。
修改强>
现在正如valdo在下面指出的那样,也有可能有一个半封闭的TCP连接,你不能再接收它,但你可以继续写入套接字,直到你完成数据发送。有关详细信息,请参阅此文章:TCP Half-Close。听起来不像你有这种情况。
在回答问题#2时,基本上有两种方法可以检测闭合的套接字。这假设套接字经历了有序关闭,这意味着对等体称为shutdown
或close
。
第一种方法是从套接字读取,在这种情况下,返回值为0.另一种方法是写入套接字,这将导致抛出SIG_PIPE信号,指示管道损坏。
为了避免信号,您可以设置MSG_NOSIGNAL
套接字选项,在这种情况下send
将返回-1并将errno
设置为EPIPE
。
答案 1 :(得分:9)
同意Robert S. Barnes。除了声称套接字现在“无效”之外。
它仍然有效。你可以使用它。您甚至可以将数据发送给对等方。你唯一不能做的就是打电话recv
。
答案 2 :(得分:2)
如果recv返回0,则表示对等方已关闭套接字。
recv不会因为它的C函数而抛出。
如果有错误,recv将返回-1。在这种情况下,您的应用程序必须检查错误类型。请注意,返回-1并不意味着对等体已关闭其套接字。
答案 3 :(得分:2)
我想您正在使用TCP与您的设备进行通信。
套接字本身仍然“有效”,但连接丢失了。
当其他主机关闭连接时,recv()
的返回值为0(这种断开连接是否正常无关紧要)
套接字函数与C
函数类似:它们不会抛出,因为它们可以在C
程序中使用,其中存在不的异常。
答案 4 :(得分:1)
鉴于您正在与Web服务器通信,我假设您正在使用TCP套接字。
回答:
套接字因断开连接而无效;他们只是进入断开状态。在它们上调用套接字操作仍然是安全的。
发生断开连接时,您不会收到任何特殊消息。如果以阻塞方式调用recv()
,它将在断开连接时返回,并且从调用返回的字节数将与您请求的字节数不匹配。
对此没有真正的答案 - 它是最初实现套接字API的方式,而我们仍然坚持使用每个实现Berkley套接字的实现。
答案 5 :(得分:0)
要纠正现有答案中的许多错误陈述:
- 这是否意味着我到目前为止使用的套接字无效。
不。这意味着对等方已关闭连接,或将其关闭以从其末端输出。您的套接字仍然有效。您可以再次调用recv()
,但是得到的只是另一个零。您也可以在其上调用send()
,如果对等方仅关闭连接以进行输出,则将发送数据。
- 断开连接时,是否收到任何特殊消息,例如空字符或其他内容。
否,您从recv()
获得零返回值。那就是它的目的。它是带外传送的,而不是在数据缓冲区中传送的。
- 如果我的套接字连接无效,那么为什么
recv()
套接字函数不抛出
因为它是C API,所以C或Unix系统调用中都没有throws
。
和SOCKET_ERROR。
因为这不是错误。
相反,为什么我会收到长度为0的数据。
您不会“接收长度为0的数据”。您收到的返回值为零,而不是数据。
答案 6 :(得分:-1)
我熟悉的几乎所有应用程序都仅使用阻止呼叫。仅当select()/ epoll()告诉您可读性时,您才读取套接字。当它可读时,您读取并接收了0个字节,便知道要关闭它。
答案 7 :(得分:-2)
如果将套接字设置为非阻塞(至少使用winsock2),则在没有数据要接收时,无论套接字的另一端是否有应用程序,您都将获得0。看到了另一端已关闭套接字的位置。 recv返回0,WSAGetLastError()返回0,但/ nothing /在另一端。 我实际上是来这里了解您如何发现另一端没有任何东西的。