网络编程释疑之:TCP连接拔掉网线后会发生什么

背景:前些天团队在进行终端设备和服务器端长连接业务的测试时,发现了这么一个情况:在拔掉设备端的网线后,再插上网线,有时可以继续正常的进行长接连请求,而且用的还是拔掉网线之前的那个长连接。但是有时却不能继续正常的长连接请求,需要重新建立一个新的长连接。让我尤感诧异的是第一种网线断开再插上后长连接可以恢复的情况,彻底颠覆了我一直抱有的一个所谓的“物理连接”的观念。究竟怎么回事,我们来探个究竟。


首先说说我自己发明的“物理连接”这个名词,不管怎么说我都是一个网络编程的"老手"。经常会给新人和其他有问题咨询我的同事灌输一个观念,只要网线拔掉了,说明物理连接都断了,更别提逻辑上的TCP长连接,再插上网线也只能再建立一个新的连接来继续进行请求。我做个简单的比喻:我理解的TCP长连接好比以前我们用的有线电话,甲和乙通话的过程中,倘若其中一人的电话线被拔掉了,连接就彻底断了。即使再插上电话线也不可能自动恢复通话,我们不得不重新拨通。

发现了插上网线后连接还会恢复的情况,我起初以为是简单的TCP套接字复用的情况,但是发现设备端并未编写自动重连的逻辑,这就太让我好奇和疑虑了。于是我找了一个同事配合我进行了多次测试,发现了拔掉网线后针对此TCP长连接可能会出现的 两种情况。

首先做下铺垫,做过网络编程的朋友应该都知道这么一个情况

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

说明网线断开对端是不能做任何感知的,除非我们配置操作系统的SO_KEEPALIVE选项,或者进行应用层心跳检测。请参考文章《网络编程释疑之:TCP半开连接的处理》。

  1. 如果网线断开的时间短暂,在SO_KEEPALIVE设定的探测时间间隔内,并且两端在此期间没有任何针对此长连接的网络操作。当连上网线后此TCP连接可以自动恢复,继续进行正常的网络操作。

  2. 如果网线断开的时间很长,超出了SO_KEEPALIVE设定的探测时间间隔,或者两端期间在此有了任何针对此长连接的网络操作。当连上网线时就会出现ETIMEDOUT或者ECONNRESET的错误。你必须重新建立一个新的长连接进行网络操作。

这件事后,我再也不敢随便发明名词了,呜呜......

发现一篇好文:《tcp连接断连问题剖析》

更多相关文章
  • 熟悉基于TCP协议进行linux高性能.高并发服务端编程的朋友肯定应该知道每个文件描述符及其所占的资源对并发量的影响.在这种7*24甚至*365不间断运行的服务器上,一个描述符被浪费,两个被浪费...如果被浪费的多了,那还何谈高并发,高性能.除去文件描述被正常占用的情况外,是什么导致了我们可用的文件 ...
  • 曾几何时我们还在寻求网络编程中C10K问题的解决方案,但是现在从硬件和操作系统支持来看单台服务器支持上万并发连接已经没有多少挑战性了.我们先假设单台服务器最多只能支持万级并发连接,其实对绝大多数应用来说已经远远足够了,但是对于一些拥有很大用户基数的互联网公司,往往面临的并发连接数是百万,千万,甚至腾 ...
  • 网络编程释疑之:TCP的TIME_WAIT状态在服务器开发中的影响
    在进行TCP高并发服务器开发时,有些规则仿佛是约定俗成的,很多朋友会依据这些规则去做,比如高并发TCP服务器中进行主动关闭的一方最好是客户端.服务器端程序最好启用SO_REUSEADDR选项,但是很多人却不知所以然,我们为什么要这么做呢?先上图可以看到执行主动关闭端和被动关闭端的各个阶段的状态,今天 ...
  • 与网络开发相关的招聘时最常被问起的问题是TCP和UDP的区别,现在几乎是道上混的都能答出来几点"比如TCP是面向连接的,UDP是无连接的:TCP是可靠的,UDP是不可靠的:",其中还有一点是"TCP是面向数据流的协议,UDP是面向数据报的协议",接下来我通常就 ...
  • 网络编程五:长连接&连接池的应用
    长连接&连接池的应用我们知道TCP是基于连接的协议,其实这个"连接"只是一个逻辑上的概念.在IP层看来, TCP和UDP仅仅是内容上稍有差别而已.TCP的"连接"仅仅是连接的两端对于四元组和sequence号的一种约定而已.在有些文章里总会提到这名词. ...
  • 网络编程释疑之:同步,异步,阻塞,非阻塞
    一讲到网络编程的I/O模型,总会涉及到这几个概念.问了很多人,没几个能清晰地讲出他们之间的区别联系,甚至在网络上也有很多不同的观点,也不知是中国文字释义的博大精深,还是本来这几个概念就是绕人不倦.今天我也来给大家讲解一下我对这几个概念的理解.既然网络上众说纷纭,不如找个权威参考一下,这个权威就是&l ...
  • @property (weak, nonatomic) IBOutlet UITextField * @property (weak, nonatomic) IBOutlet UITextField * - ( - (IBAction)login:( [MBProgressHUD showError ...
  • 引言 每次使用socket通信,都会有很对相似的操作.本文,会对TCP与UDP通信做一简单封装,并生成动态库. 代码 my_socket.h != (*local_sfd = socket(AF_INET, SOCK_STREAM, )), != (*local_sfd = socket(AF_IN ...
一周排行
  • 初衷:在2011年初我学习交换机链路聚合技术的时候,心中一直有一个疑问:交换机收到一个报文,到达聚合口的时候,是怎么选择成员口出去的呢?是随机选的吗?还是按成员编号从小到大或从大到小轮循?如果选择源IP算法,是怎么实 ...
  • debian系统python+uwsgi+nginx实现web环境
    1,python web部署的实现:    python+uwsgi+nginx实现web ...
  • Java性能优化之String篇
    原文:http://www.ibm.com/developerworks/cn/java/ ...
  • C#:友元程序集
    C#中的访问修饰符Internal可以说是介于Public和Private之间,可以使类型 ...
  • 团队文化之舒适区和挑战区 舒适区和挑战区想要进步,就要走出舒适区,直面挑战!自我挑战要面临的是不舒服.痛苦,要做的是坚持,再坚持!     舒适区是一个自我的安全空间,由四面墙构成:固定的环境.固定的思路.固定的形象 ...
  • 亲测可行! 这个方法在支持控制台(审查元素)的浏览器上皆可实现,比如典型的 Chrome.Firefox 以及 Chorme 核心的浏览器诸如 360浏览器.百度浏览器等.(IE好像不行)方法非常简单,只需两步: 1 ...
  • Linux有问必答:如何在Apache网站服务器上关闭服务器签名
    问题:每当Apache2网站服务器返回错误页时(如,404 页面无法找到,403 禁止访问 ...
  • 最近过的最短路题目稍微总结一下,顺便写一下模板,最短路算法众多有floyd.dij.bell-man.spfa,速度最快就是dij+优先队列或者dij+堆排序,spfa理论上很快o(ke)但实际并不一定不过spfa传 ...
  • linux硬盘分区格式化及挂载
                                                  ...
  • “有人说:女生到社会上会遇到比学校更优秀的男生,而男生很难找到比在学校更好的女生,我现在告诉你,这句话你们都理解错了.这句话的意思是:男生在校园都还不成熟,19到25岁的男孩一般都比同龄女孩显得放不开,但到社会上,很 ...