A机器与B机器网络connect成功后,断电时的网络状态?

简介: A机器与B机器网络connect成功后,断电时的网络状态?

如果A机器与B机器网络connect成功后从未互发过数据,此时其中一机器突然断电,则另外一台机器与断电的机器之间的网络连接处于哪种状态?

笔者实测如下:

虚拟机A:

CentOS 7,192.168.133.131,TCP Server

虚拟机B:

CentOS 7,192.168.133.128,TCP Client

1、建立连接时:

A机器

[root@localhost ~]# netstat -nalp|grep 1883
tcp 0 0 0.0.0.0:1883 0.0.0.0:* LISTEN 48261/epltest
tcp 0 0 192.168.133.131:1883 192.168.133.128:39170 ESTABLISHED 48261/epltest

B机器
[root@localhost firecat]# netstat -nalp|grep 1883
tcp 0 0 192.168.133.128:39170 192.168.133.131:1883 ESTABLISHED 7470/./eplClient

2、B机器断电时,A机器查看状态如下:

[root@localhost ~]# netstat -nalp|grep 1883
tcp 0 0 0.0.0.0:1883 0.0.0.0:* LISTEN 48261/epltest
tcp 0 0 192.168.133.131:1883 192.168.133.128:39170 ESTABLISHED 48261/epltest

结论:断电后,继续保持ESTABLISHED的网络状态。

3、笔者继续实测,让A断电,B保持,结论还是一样,ESTABLISHED。

4、如果A不变,B机器kill client进程,则B机器会出现TIME_WAIT的网络状态。

[root@localhost firecat]# kill -9 7459
[root@localhost firecat]# netstat -nalp|grep 1883
tcp 0 0 192.168.133.128:60114 192.168.133.131:1883 TIME_WAIT -

5、我们如果手动拔掉网线,在没有心跳机制的前提下,现象也是一样的。

6、具体原因如下:

什么是半开连接?

当客户端与服务器建立起正常的TCP连接后,如果客户主机掉线(网线断开)、电源掉电、或系统崩溃,服务器进程将永远不会知道(通过我们常用的select,epoll监测不到断开或错误事件),如果不主动处理或重启系统的话对于服务端来说会一直维持着这个连接,任凭服务端进程如何望穿秋水,也永远再等不到客户端的任何回应。这种情况就是半开连接,浪费了服务器端可用的文件描述符。

如何处理?

熟悉套接字通用选项的朋友一定已经有了想法。TCP套接字不是有个保持存活选项SO_KEEPALIVE嘛,如果在两个小时之内在该套接字的任何一个方向上都没数据交换,TCP就自动给对端发送一个保持存活探测分节,如果此TCP探测分节的响应为RST,说明对端已经崩溃且已经重新启动,该套接字的待处理错误被置为ECONNRESET,套接字本身则被关闭。如果没有对此TCP探测分节的任何响应,该套接字的处理错误就被置为ETIMEOUT,套接字本身则被关闭。

确实,这个选项确实可以处理我们前面遇到的TCP半开连接的问题,但是默认两小时间隔探测的实时性是不是差了些呢?当然,我们可以通过修改内核参数改小时间间隔,完美了吧?但是必须注意的是大多数内核是基于整个内核维护这些时间参数的,而不是基于每个套接字维护的,因此如果把无活动周期从两小时改为(比如)2分钟,那将影响到该主机上所有开启了此选项的套接字。我想大家都不会愿意承担服务器端的这种不确定性吧。另外,心跳除了说明应用程序还活着(进程存在,网络畅通),更重要的是表明应用程序能正常工作。而SO_KEEPALIVE由操作系统负责探查,即便是进程死锁或有其他异常,操作系统也会正常收发TCP keepalive消息,而对方无法得知这一异常。

没关系,其实我们可以在应用层模拟SO_KEEPALIVE的方式,用心跳包来模拟保活探测分节。由于服务器通常要承担成千上万的并发连接,所以肯定是由客户端在应用层进行心跳来模拟保活探测分节,客户端多次收不到服务器的响应时可终止此TCP连接,而服务端可监测客户端的心跳包,若在一定时间间隔内未收到任何来自客户端的心跳包则可以终止此TCP连接,这样就有效避免了TCP半开连接的情况。

相关文章
|
网络协议 Unix Linux
计算机网络 套接字函数 | socket、bind、listen、accept、connect
计算机网络 套接字函数 | socket、bind、listen、accept、connect
126 0
|
网络协议 Unix Linux
Linux网络管理之netstat命令– 显示网络状态
netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多播成员 (Multicast Memberships) 等等。
167 0
Linux网络管理之netstat命令– 显示网络状态
|
Android开发
android 网络实时监听网络状态变化 及 网络类型判断
android 网络实时监听网络状态变化 及 网络类型判断
DayDayUp:《机器崛起前传》第二十二章【蹒跚而来】读后感(文章源自网络)—听课笔记
DayDayUp:《机器崛起前传》第二十二章【蹒跚而来】读后感(文章源自网络)—听课笔记
|
缓存 运维 负载均衡
一个支持高网络吞吐量、基于机器性能评分的TCP负载均衡器gobalan
作者最近用golang实现了一个TCP负载均衡器,灵感来自grpc。几个主要的特性就是: - 支持高网络吞吐量 - 实现了基于机器性能评分来分配worker节点的负载均衡算法 - 尽量做到薄客户端,降低客户端复杂性
1552 0
|
机器学习/深度学习 数据可视化 大数据
机器都会学习了,你的神经网络还跑不动?来看看这些建议
在机器学习的研究过程中,学到经验和知识的并不仅仅是机器,我们人类也积累的丰富的经验,本文就将给你几条最实用的研究建议。
1082 0