简体   繁体   中英

Socket recv() function

In c++, in windows OS, on the recv() call for TCP socket , if the socket connection is closed somehow, the recv() will return immediately or will it hang?

What would be result(immediately returns or hangs) in the blocking and non blocking socket? I am using socket version 2.

Thanks in advance.

As documented depending of how the connection was closed it should more or less immediately with a return value of SOCKET_ERROR in a non graceful case and set WSAGetLastError to one of the possible reasons like WSAENOTCONN or would just return 0 in the graceful connection close scenario. This would be the same between blocking and nonblocking sockets.

If the socket is connection oriented and the remote side has shut down the connection gracefully, and all data has been received, a recv will complete immediately with zero bytes received. If the connection has been reset, a recv will fail with the error WSAECONNRESET.

However, since I know the Windows API does not always work as documented, I recommend to test it.

如果您的recv()基于BSD(几乎都是基于BSD的),则无论连接是阻塞还是非阻塞,如果关闭连接(根据本地状态),它将立即返回。

recv() will return 0 upon a graceful disconnect, ie the peer shutdown its end of the connection and its socket stack sent a FIN packet to your socket stack. You are pretty much guaranteed to get this result immediately, whether you use a blocking or non-blocking socket.

recv() will return -1 on any other error, including an abnormal connection loss. You need to use WSAGetLastError() to find out what actually happened. For a lost connection on a blocking socket, you will usually get an error code such as WSAECONNRESET or WSAECONNABORTED . For a lost connection on a non-blocking socket, it is possible that recv() may report an WSAEWOULDBLOCK error immediately and then report the actual error at some later time, maybe via select() with an exception fd_set , or an asynchronous notification, depending on how you implement your non-blocking logic.

However, either way, you are NOT guaranteed to get a failure result on a lost connection in any timely manner! It MAY take some time (seconds, minutes, can even be hours in rare cases) before the OS deems the connection is actually lost and invalidates the socket connection. TCP is designed to recover lost connections when possible, so it has to account for temporary network outages and such, so there are internal timeouts. You don't see that in your code, it happens in the background.

If you don't want to wait for the OS to timeout internally, you can always use your own timeout in your code, such as via select() , setsocktopt(SO_RCVTIMEO) , TCP keep-alives ( setsockopt(SO_KEEPALIVE) or WSAIoCtl(SIO_KEEPALIVE_VALS) ), etc. You may still not get a failure immediately , but you will get it sooner rather than later.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM