《网络编程释疑之:TCP半开连接的处理》这篇文章主要讲述了网络异常的出现、以及如何在服务端解决存在的网络异常。同时,客户端能否及时检测到自身的网络异常(比如网络禁用,网线断开......)也同样影响着客户端的正常逻辑,下面我就通过自己的实验和实践来给大家说明下。
场景是这样的,客户端和服务端建立起一个长连接,并且通过一个心跳来维持上线状态、同时也为了解决上面所说的TCP半开连接问题。客户端在自身出现网络异常的情况下下线,但是一旦自身网络恢复要自动恢复此前的正常逻辑。这种情况在现实场景中有很多,比如底层协议为TCP的即时聊天软件在自身网络异常的情况下掉线,一旦网络恢复就自动上线,还有其他很多的基于TCP自动重连应用。这样,要求我们能及时快速的响应到网络异常并开始新的自动重连动作。
当然,我们可以从操作系统的层次去迅速响应到网络异常(比如网络禁用,网线断开...),但是我目前还没找到特别好的方案,望有过实践的朋友可以指导一二。我便退一步选用了在网络应用层进行这种网络异常的检查,在这个过程中选用了libevent网络库的
void bufferevent_setcb (struct bufferevent *bufev, bufferevent_data_cb readcb, bufferevent_data_cb writecb, bufferevent_event_cb eventcb, void *cbarg)
方法,利用eventcb回调来响应网络关闭或异常事件。之所以写这篇文章,就是因为在这过程中发现了一些不同的网络异常行为导致的处理不同,甚至在不同的操作系统下也有不同。
Windows系统
禁用网络会立马响应eventcb回调,对应的事件是BEV_EVENT_ERROR
。
而断开网线不会立马响应eventcb回调,而是在下一次利用此socket进行数据操作时响应eventcb回调,对应的事件为BEV_EVENT_EOF
。
Linux系统(CentOS)
禁用网络和断开网线都不会响应eventcb回调,需要自己去处理关闭socket描述符并清理响应libevent的资源。
Android系统
奇怪的是同是linux内核,但是在禁用网络和wifi断开情况下的处理却和windows系统类似。
另外分享给大家一篇文章《网络异常检查》