什么情况下在服务器程序退出后,客户端程序的recv没有任何响应?

时间:2022-10-30 20:55:00
目前我们这边用CORBA进行编程(ACE/TAO),底层是基于SOCKET/TCP的。但是经常出现一个问题,就是 服务器 那边异常退出以后,客户端这边长期无响应。调试到CORBA内部,发现在服务器异常退出后,客户端这边的 SOCKET 的 recv 方法(阻塞调用方式)却长期没有返回,因而造成无响应。
按照道理说,如果服务器那边的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.

#5


对方SOCKET断掉,阻塞模式会一直等待数据不返回,导致进程占用cpu 100%

#6


需要设置心跳包,setsockopt里面设SO_KEEPALIVE 

#7


我的意思是,当我方进程阻塞调用 recv 时,对应SOCKET连接 的 对方进程处理过程中自己异常退出了,这个时候,我方进程种的 SOCKET 应该是能够检测到对端异常退出了,然后 recv 会返回值为 -1 的,不是吗?只有在网线拔掉等物理硬件导致网络异常,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.

#5


对方SOCKET断掉,阻塞模式会一直等待数据不返回,导致进程占用cpu 100%

#6


需要设置心跳包,setsockopt里面设SO_KEEPALIVE 

#7


我的意思是,当我方进程阻塞调用 recv 时,对应SOCKET连接 的 对方进程处理过程中自己异常退出了,这个时候,我方进程种的 SOCKET 应该是能够检测到对端异常退出了,然后 recv 会返回值为 -1 的,不是吗?只有在网线拔掉等物理硬件导致网络异常,recv才会检测不到,这个时候才需要使用心跳包啊。
我的情况恰恰就是,当没有物理硬件异常,对端程序自己异常退出的情况下,我这边的 recv 却一直阻塞,没有返回!我不知道这种情况为何会发生。
另外,我这里不好设置超时时间的,因为对应的各种网络命令的执行时间长短不一,设置短了会影响正常流程。

#8


不要以“只有在网线拔掉等物理硬件导致网络异常,recv才会检测不到”这种表象来看socket,真正的recv检测不到是因为收不到FIN(正常4次握手关闭)或RESET(强制关闭),你抓下包看看,收到FIN并且你的读缓冲已经无数据时,你的recv一定返回网络异常,如果收到RESET则是马上recv返回。TCP在网络异常上的判断实际上还是不完善的,上层如果要做的好一些,必须要有自己的心跳机制(最好不要依赖Keep-alive)

#9


找到原因了,原因在于中间网络瞬断导致丢包,因此recv 就一直接收不到,导致阻塞了。感谢大家参与讨论。

#10


tcp网络瞬断导致丢包?recv收不到?呵呵.........................................怎么可能