按照道理说,如果服务器那边的SOCKET异常退出的话,应该客户端这边的 recv 会返回 -1 才对啊,为何什么都没有收到呢?各位大侠有无遇到这种情况?如何解决?
谢谢
10 个解决方案
#1
socket的阻塞模式会没有响应。
#2
不是吧,在阻塞模式下,对方SOCKET断掉,我方的 recv 也应该会返回的啊,返回值可能为 0或-1或其它错误码,不会一直不返回吧。
#3
阻塞模式会一直等待数据不返回。
#4
不是吧,在阻塞模式下,对方SOCKET断掉,我方的 recv 也应该会返回的啊,返回值可能为 0或-1或其它错误码,不会一直不返回吧。
MSDN:
If no incoming data is available at the socket, the recv call blocks and waits for data to arrive according to the blocking rules defined for WSARecv with the MSG_PARTIAL flag not set unless the socket is nonblocking. In this case, a value of SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK. The select, WSAAsyncSelect, or WSAEventSelect functions can be used to determine when more data arrives.
MSDN:
If no incoming data is available at the socket, the recv call blocks and waits for data to arrive according to the blocking rules defined for WSARecv with the MSG_PARTIAL flag not set unless the socket is nonblocking. In this case, a value of SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK. The select, WSAAsyncSelect, or WSAEventSelect functions can be used to determine when more data arrives.
#5
对方SOCKET断掉,阻塞模式会一直等待数据不返回,导致进程占用cpu 100%
#6
需要设置心跳包,setsockopt里面设SO_KEEPALIVE
#7
我的意思是,当我方进程阻塞调用 recv 时,对应SOCKET连接 的 对方进程处理过程中自己异常退出了,这个时候,我方进程种的 SOCKET 应该是能够检测到对端异常退出了,然后 recv 会返回值为 -1 的,不是吗?只有在网线拔掉等物理硬件导致网络异常,recv才会检测不到,这个时候才需要使用心跳包啊。
我的情况恰恰就是,当没有物理硬件异常,对端程序自己异常退出的情况下,我这边的 recv 却一直阻塞,没有返回!我不知道这种情况为何会发生。
另外,我这里不好设置超时时间的,因为对应的各种网络命令的执行时间长短不一,设置短了会影响正常流程。
我的情况恰恰就是,当没有物理硬件异常,对端程序自己异常退出的情况下,我这边的 recv 却一直阻塞,没有返回!我不知道这种情况为何会发生。
另外,我这里不好设置超时时间的,因为对应的各种网络命令的执行时间长短不一,设置短了会影响正常流程。
#8
不要以“只有在网线拔掉等物理硬件导致网络异常,recv才会检测不到”这种表象来看socket,真正的recv检测不到是因为收不到FIN(正常4次握手关闭)或RESET(强制关闭),你抓下包看看,收到FIN并且你的读缓冲已经无数据时,你的recv一定返回网络异常,如果收到RESET则是马上recv返回。TCP在网络异常上的判断实际上还是不完善的,上层如果要做的好一些,必须要有自己的心跳机制(最好不要依赖Keep-alive)
#9
找到原因了,原因在于中间网络瞬断导致丢包,因此recv 就一直接收不到,导致阻塞了。感谢大家参与讨论。
#10
tcp网络瞬断导致丢包?recv收不到?呵呵.........................................怎么可能
#1
socket的阻塞模式会没有响应。
#2
不是吧,在阻塞模式下,对方SOCKET断掉,我方的 recv 也应该会返回的啊,返回值可能为 0或-1或其它错误码,不会一直不返回吧。
#3
阻塞模式会一直等待数据不返回。
#4
不是吧,在阻塞模式下,对方SOCKET断掉,我方的 recv 也应该会返回的啊,返回值可能为 0或-1或其它错误码,不会一直不返回吧。
MSDN:
If no incoming data is available at the socket, the recv call blocks and waits for data to arrive according to the blocking rules defined for WSARecv with the MSG_PARTIAL flag not set unless the socket is nonblocking. In this case, a value of SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK. The select, WSAAsyncSelect, or WSAEventSelect functions can be used to determine when more data arrives.
MSDN:
If no incoming data is available at the socket, the recv call blocks and waits for data to arrive according to the blocking rules defined for WSARecv with the MSG_PARTIAL flag not set unless the socket is nonblocking. In this case, a value of SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK. The select, WSAAsyncSelect, or WSAEventSelect functions can be used to determine when more data arrives.
#5
对方SOCKET断掉,阻塞模式会一直等待数据不返回,导致进程占用cpu 100%
#6
需要设置心跳包,setsockopt里面设SO_KEEPALIVE
#7
我的意思是,当我方进程阻塞调用 recv 时,对应SOCKET连接 的 对方进程处理过程中自己异常退出了,这个时候,我方进程种的 SOCKET 应该是能够检测到对端异常退出了,然后 recv 会返回值为 -1 的,不是吗?只有在网线拔掉等物理硬件导致网络异常,recv才会检测不到,这个时候才需要使用心跳包啊。
我的情况恰恰就是,当没有物理硬件异常,对端程序自己异常退出的情况下,我这边的 recv 却一直阻塞,没有返回!我不知道这种情况为何会发生。
另外,我这里不好设置超时时间的,因为对应的各种网络命令的执行时间长短不一,设置短了会影响正常流程。
我的情况恰恰就是,当没有物理硬件异常,对端程序自己异常退出的情况下,我这边的 recv 却一直阻塞,没有返回!我不知道这种情况为何会发生。
另外,我这里不好设置超时时间的,因为对应的各种网络命令的执行时间长短不一,设置短了会影响正常流程。
#8
不要以“只有在网线拔掉等物理硬件导致网络异常,recv才会检测不到”这种表象来看socket,真正的recv检测不到是因为收不到FIN(正常4次握手关闭)或RESET(强制关闭),你抓下包看看,收到FIN并且你的读缓冲已经无数据时,你的recv一定返回网络异常,如果收到RESET则是马上recv返回。TCP在网络异常上的判断实际上还是不完善的,上层如果要做的好一些,必须要有自己的心跳机制(最好不要依赖Keep-alive)
#9
找到原因了,原因在于中间网络瞬断导致丢包,因此recv 就一直接收不到,导致阻塞了。感谢大家参与讨论。
#10
tcp网络瞬断导致丢包?recv收不到?呵呵.........................................怎么可能