C语言 recv() 套接字函数返回长度为 0 的数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3091010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
recv() socket function returning data with length as 0
提问by ckv
I am having an application which established a socket connection on a port number 5005 with another device(hardware device with a web server).
我有一个应用程序,它在端口号 5005 上与另一台设备(带有 Web 服务器的硬件设备)建立了套接字连接。
Now if my hardware device disconnects then i loose connection with the device.
现在,如果我的硬件设备断开连接,那么我会与设备断开连接。
Does this mean that the socket i was using until now becomes invalid.
Do i get any special message like null character or something when this disconnect happens.
- If the socket connection i was having became invalid then why doesnt the recv() socket function throw and SOCKET_ERROR. Instead why do i receive data of 0 length.
这是否意味着我直到现在使用的套接字变得无效。
当这种断开连接发生时,我是否收到任何特殊消息,如空字符或其他内容。
- 如果套接字连接无效,那么为什么 recv() 套接字函数不抛出和 SOCKET_ERROR。相反,为什么我会收到长度为 0 的数据。
Thanks
谢谢
回答by Robert S. Barnes
When recvreturns a value of 0 that means the connection has been closed.
当recv返回值 0 时,表示连接已关闭。
See the recvman page:
请参阅recv手册页:
These calls return the number of bytes received, or -1 if an error occurred. The return value will be 0 when the peer has performed an orderly shutdown.
这些调用返回接收到的字节数,如果发生错误,则返回 -1。当对等端执行有序关闭时,返回值将为 0。
In answer to question #1, yes the socket is now invalid. You must create a new socket and connection for further communications.
在回答问题 #1 时,是的,套接字现在无效。您必须创建一个新的套接字和连接以进行进一步的通信。
Edit
编辑
Now as valdo pointed out below, there is also the possibility of having a half-closed TCP connection in which you can't receive any more but you can keep writing to the socket until you've finished sending your data. See this article for more details: TCP Half-Close. It doesn't sound like you have this situation though.
现在正如 valdo 在下面指出的那样,也有可能有一个半关闭的 TCP 连接,在该连接中您无法再接收任何信息,但您可以继续写入套接字,直到您完成发送数据。有关更多详细信息,请参阅此文章: TCP Half-Close。听起来你没有这种情况。
In answer to question #2, there are basically two ways to detect a closed socket. This assumes that the socket went through an orderly shutdown, meaning the peer called either shutdownor close.
在回答问题#2 时,基本上有两种方法可以检测关闭的套接字。这假设套接字经历了有序关闭,这意味着对等方调用了shutdown或close。
The first method is to read from the socket in which case you get a return value of 0. The other method is to write to the socket, which will cause the SIG_PIPE signal to be thrown indicating a broken pipe.
第一种方法是从套接字读取,在这种情况下,您将获得返回值 0。另一种方法是写入套接字,这将导致抛出 SIG_PIPE 信号,指示管道损坏。
In order to avoid the signal, you can set the MSG_NOSIGNALsocket option in which case sendwould return -1 and set errnoto EPIPE.
为了避免信号,您可以设置MSG_NOSIGNAL套接字选项,在这种情况下send将返回 -1 并设置errno为EPIPE。
回答by valdo
Agree with Robert S. Barnes. Except the claim that the socket is now "invalid".
同意罗伯特·S·巴恩斯的观点。除了声称套接字现在“无效”。
It's still valid. You can use it. You can even send data to the peer. The only thing you can't do with it is call recv.
它仍然有效。你可以使用它。您甚至可以向对等方发送数据。你唯一不能用它做的就是 call recv。
回答by ereOn
I suppose you're using TCP to communicate with your device.
我想您正在使用 TCP 与您的设备进行通信。
The socket itself is still "valid", however the the connection was lost.
You get a return value of 0 for
recv()when the connection was closed by the other host (wether this disconnection was graceful or not doesn't matter)socket functions are like
Cfunctions: they don't throw because they can be used inCprograms, where exceptions do notexist.
套接字本身仍然“有效”,但是连接丢失了。
recv()当连接被另一台主机关闭时,您会得到 0 的返回值(这种断开是否正常无关紧要)套接字函数就像
C函数:它们不会抛出C异常,因为它们可以在不存在异常的程序中使用。
回答by sashang
If recv returns 0 this means that the peer has closed the socket.
如果 recv 返回 0,则表示对等方已关闭套接字。
recv won't throw because its a C function.
recv 不会抛出,因为它是一个 C 函数。
If there's an error recv will return -1. In which case your application has to check the type of error. Note that a return of -1 does not imply that the peer has closed its socket.
如果有错误 recv 将返回 -1。在这种情况下,您的应用程序必须检查错误类型。请注意,返回 -1 并不意味着对等方已关闭其套接字。
回答by Blair Holloway
Given that you're talking to a web server, I'll assume you're using TCP sockets.
鉴于您正在与 Web 服务器通话,我假设您使用的是 TCP 套接字。
To answer:
回答:
Sockets don't become invalid due to a disconnect; they simply go into a disconnected state. It's still safe to call socket operations on them.
You don't get any special messages when the disconnect occurs. If you call
recv()in a blocking fashion, it will return when disconnected, and the number of bytes returned from the call won't match the number of bytes you asked for.There isn't really an answer to this - it's how the socket API was implemented originally, and we're stuck with that implementation as everyoneimplements Berkley Sockets.
套接字不会因断开连接而失效;它们只是进入断开连接状态。对它们调用套接字操作仍然是安全的。
断开连接时,您不会收到任何特殊消息。如果您
recv()以阻塞方式调用,它会在断开连接时返回,并且从调用返回的字节数将与您要求的字节数不匹配。对此并没有真正的答案 - 这就是套接字 API 最初是如何实现的,我们坚持使用该实现,因为每个人都实现了伯克利套接字。
回答by user207421
To correct numerous misstatements in the existing answers:
要纠正现有答案中的大量错误陈述:
- Does this mean that the socket i was using until now becomes invalid.
- 这是否意味着我直到现在使用的套接字变得无效。
No. It means the peer has closed the connection, or shut it down for output from his end. Your socket is still valid. You can call recv()again, but all you will get is another zero. You can call send()on it too, and if the peer has only shutdown the connection for output the data will be sent.
否。这意味着对等方已关闭连接,或关闭它以从他的一端输出。您的套接字仍然有效。你可以recv()再次打电话,但你得到的只是另一个零。您也可以调用send()它,如果对等方仅关闭了输出连接,则将发送数据。
- Do I get any special message like null character or something when this disconnect happens.
- 发生这种断开连接时,我是否收到任何特殊消息,例如空字符或其他内容。
No, you get zero return value from recv(). That's what it's for. It is delivered out-of-band, not in the data buffer.
不,您从recv(). 这就是它的用途。它是在带外传送的,而不是在数据缓冲区中传送。
- If the socket connection i was having became invalid then why doesnt the
recv()socket function throw
- 如果套接字连接无效,那么为什么
recv()套接字函数不抛出
Because it's a C API, and there are no throwsin C, or in Unix system calls either.
因为它是一个 C API,throws在 C 或 Unix 系统调用中都没有。
and SOCKET_ERROR.
和 SOCKET_ERROR。
Because it isn't an error.
因为这不是错误。
Instead why do i receive data of 0 length.
相反,为什么我会收到长度为 0 的数据。
You don't 'receive data of 0 length'. You receive a return value of zero instead ofdata.
您不会“接收长度为 0 的数据”。您收到的返回值为零而不是数据。

