原文:http://blog.csdn.net/wangpengqi/article/details/17245349

这就有个细节,一次http请求,谁会先断开TCP连接?什么情况下客户端先断,什么情况下服务端先断?

百度后,找到原因,主要有http1.0和http1.1之间保持连接的差异以及http头中connection、content-length、Transfer-encoding等参数有关;

当然,在nginx中,对于http1.0与http1.1也是支持长连接的。什么是长连接呢?我们知道,http请求是基于TCP协议之上的,那么,当客户端在发起请求前,需要先与服务端建立TCP连接,而每一次的TCP连接是需要三次握手来确定的,如果客户端与服务端之间网络差一点,这三次交互消费的时间会比较多,而且三次交互也会带来网络流量。当然,当连接断开后,也会有四次的交互,当然对用户体验来说就不重要了。而http请求是请求应答式的,如果我们能知道每个请求头与响应体的长度,那么我们是可以在一个连接上面执行多个请求的,这就是所谓的长连接,但前提条件是我们先得确定请求头与响应体的长度。对于请求来说,如果当前请求需要有body,如POST请求,那么nginx就需要客户端在请求头中指定content-length来表明body的大小,否则返回400错误。也就是说,请求体的长度是确定的,那么响应体的长度呢?先来看看http协议中关于响应body长度的确定:

  1. 对于http1.0协议来说,如果响应头中有content-length头,则以content-length的长度就可以知道body的长度了,客户端在接收body时,就可以依照这个长度来接收数据,接收完后,就表示这个请求完成了。而如果没有content-length头,则客户端会一直接收数据,直到服务端主动断开连接,才表示body接收完了。
  2. 而对于http1.1协议来说,如果响应头中的Transfer-encoding为chunked传输,则表示body是流式输出,body会被分成多个块,每块的开始会标识出当前块的长度,此时,body不需要通过长度来指定。如果是非chunked传输,而且有content-length,则按照content-length来接收数据。否则,如果是非chunked,并且没有content-length,则客户端接收数据,直到服务端主动断开连接。

从上面,我们可以看到,除了http1.0不带content-length以及http1.1非chunked不带content-length外,body的长度是可知的。此时,当服务端在输出完body之后,会可以考虑使用长连接。能否使用长连接,也是有条件限制的。如果客户端的请求头中的connection为close,则表示客户端需要关掉长连接,如果为keep-alive,则客户端需要打开长连接,如果客户端的请求中没有connection这个头,那么根据协议,如果是http1.0,则默认为close,如果是http1.1,则默认为keep-alive。如果结果为keepalive,那么,nginx在输出完响应体后,会设置当前连接的keepalive属性,然后等待客户端下一次请求。当然,nginx不可能一直等待下去,如果客户端一直不发数据过来,岂不是一直占用这个连接?所以当nginx设置了keepalive等待下一次的请求时,同时也会设置一个最大等待时间,这个时间是通过选项keepalive_timeout来配置的,如果配置为0,则表示关掉keepalive,此时,http版本无论是1.1还是1.0,客户端的connection不管是close还是keepalive,都会强制为close。

如果服务端最后的决定是keepalive打开,那么在响应的http头里面,也会包含有connection头域,其值是”Keep-Alive”,否则就是”Close”。如果connection值为close,那么在nginx响应完数据后,会主动关掉连接。所以,对于请求量比较大的nginx来说,关掉keepalive最后会产生比较多的time-wait状态的socket。一般来说,当客户端的一次访问,需要多次访问同一个server时,打开keepalive的优势非常大,比如图片服务器,通常一个网页会包含很多个图片。打开keepalive也会大量减少time-wait的数量。

——————————————————————————————————————————————————————————————————————————

TIME_WAIT是什么?

从下图可以看出: TIME_WAIT 产生在主动断开连接的一方

在TCP断开的过程中会有四个状态变化过程,如下图所示:

 
 
在连接撤销过程中,有如下过程:                                          
1.HOST1上的应用程序关闭己方的连接导致TCP发送一个FIN消息给HOST2。
2.HOST2发送一个确认消息给HOST1,并且HOST2把FIN作为EOF递交给HOST2上的应用程序。
3.一段时间过后,HOST2上的应用程序关闭它那边的连接,引发一个FIN消息给HOST1。
4.HOST1给HOST2发送一个确认消息,然后HOST2关闭连接并释放资源,然而,HOST1却没有关闭连接,而是进入了TIME_WAIT状态,并为两个最大段生存时间(2MSL)保留在此状态.
 
为什么需要TIME_WAIT?
 
 
1.因为在第四步的时候,HOST1发送的ACK可能丢失并导致HOST2重新发送FIN消息,TIME_WAIT维护连接状态.
  如果执行主动关闭的一方HOST1 不进入到TIME_WAIT状态就关闭连接那会发生什么呢?当重传的FIN消息到达时,因为TCP已经不再有连接的信息了,所以就用RST(重新启动)消息应答,导致HOST2进入错误的状态而不是有序终止状态,如果发送最后ACK消息的一方处于TIME_WAIT状态并仍然记录着连接的信息,它就可以正确的响应对等方HOST2的FIN消息了.
2.TIME_WAIT为连接中”离群的段”提供从网络中消失的时间.
  考虑一下,如果延迟或者重传段在连接关闭后到达时会发生什么呢?通常情况下,因为TCP仅仅丢弃该数据并响应RST消息,所以这不会造成任何问题。当RST消息到达发出延时段的主机时,因为该主机也没有记录连接的任何信息,所以它也丢弃该段。然而,如果两个相同主机之间又建立了一个具有相同端口号的新连接,那么离群的段就可能被看成是新连接的,如果离群的段中数据的任何序列号恰恰在新连接的当前接收窗口中,数据就会被重新接收,其结果就是破坏新连接

TCP 连接中的TIME_WAIT的更多相关文章

  1. tcp连接的状态变迁以及如何调整tcp连接中处于time_wait的时间

    一.状态变迁图 二.time_wait状态 针对time_wait和close_wait有个简单的描述帮助理解: Due to the way TCP/IP works, connections ca ...

  2. TCP连接中time_wait在开发中的影响-搜人以鱼不如授之以渔

    根据TCP协议定义的3次握手断开连接规定,发起socket主动关闭的一方socket将进入TIME_WAIT状态,TIME_WAIT状态将持续2个MSL(Max Segment Lifetime),T ...

  3. 服务器TCP连接中 TIME_WAIT 状态过多

    今天查看服务器的TCP连接数,发现其中 TIME_WAIT 状态的太多了: # netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a ...

  4. 修改Linux内核参数,减少TCP连接中的TIME-WAIT

    一台服务器CPU和内存资源额定有限的情况下,如何提高服务器的性能是作为系统运维的重要工作.要提高Linux系统下的负载能力,当网站发展起来之后,web连接数过多的问题就会日益明显.在节省成本的情况下, ...

  5. 【NodeJs】Ctrl+C在Linux平台和Windows平台下的TCP连接中的不同表现

    Linux平台:CentOS release 6.5 (Final) Windows平台:Windows 7 旗舰版 服务器端代码如下: var net = require('net'); var s ...

  6. 几种TCP连接中出现RST的情况(转载)

    TCP RST 网络 linux 目录[-] 1 端口未打开 2 请求超时 3 提前关闭 4 在一个已关闭的socket上收到数据 总结 参考文献: 应该没有人会质疑,现在是一个网络时代了.应该不少程 ...

  7. TCP/IP详解--TCP连接中TIME_WAIT状态过多

    TIMEWAIT状态本身和应用层的客户端或者服务器是没有关系的.仅仅是主动关闭的一方,在使用FIN|ACK|FIN|ACK四分组正常关闭TCP连接的时候会出现这个TIMEWAIT.服务器在处理客户端请 ...

  8. TCP 连接关闭及TIME_WAIT探究

    这里主要记录一下TCP连接在关闭的时刻,有哪些细节问题.方便在以后的程序设计中能够注意这些细节, 以避免出现这些错误.首先我们来看一下TCP的状态转换图.如<unix网络编程>卷一所示如下 ...

  9. TCP连接中的状态

    1. 正常状态转换 我们用图 3-13 来显示在正常的 TCP 连接的建立与终止过程中,客户与服务器所经历的不同状态.读者可以对照图 3-12 来阅读,使用图 3-12 的状态图来跟踪图 3-13 的 ...

随机推荐

  1. java常量和变量的定义规则,变长参数的使用

    首先是定义的一般规则,类名首字母全部大写,常量全部大写用下划线分隔,变量用驼峰形式.注意使用long赋值用L时不能写小写的L要写大写的,不然会和数字“1”傻傻分不清. 下面是举例: public cl ...

  2. js基础和工具库

    /* * 作者: 胡乐 * 2015/4/18 * js 基础 和 工具库 * * * */ //根据获取对象 function hGetId(id){ return document.getElem ...

  3. ebtables

    ebtables是以太网桥防火墙,以太网工作在数据链路层,ebtables过滤数据链路层包.2.6内核内置了ebtables,要使用它必须先按装她的用户空间工具(ebtables-V2.0.6),安装 ...

  4. HDU1686:Oulipo

    Problem Description The French author Georges Perec (1936–1982) once wrote a book, La disparition, w ...

  5. 循环ip段 转载 出处不明

    public struct IP         {             public byte A;             public byte B;             public  ...

  6. Linux入门学习教程:虚拟机体验之KVM篇

    本文中可以学习到的命令: 1. aptitude 是apt-get 不会产生垃圾的版本 2.       dpkg -L virtualbox 显示属于该包的文件 lsmod | grep kvmfi ...

  7. 【转载】CentOS 6.4下PXE+Kickstart无人值守安装操作系统

    [转载]CentOS 6.4下PXE+Kickstart无人值守安装操作系统 转自:CentOS 6.4下PXE+Kickstart无人值守安装操作系统 - David_Tang - 博客园 http ...

  8. POJ 3597 种类数 数学+递推

    http://poj.org/problem?id=3597 题目大意:把一个正多边形分成数个三角形或者四边形,问有多少种方案. 思路:http://www.cnblogs.com/Ritchie/p ...

  9. 安装你自己的perl modules

    来源: http://www.cnblogs.com/itech/archive/2012/12/17/2822044.html 安装你自己的perl modules.当没有root权限的时候,需要安 ...

  10. ORA-12170: TNS:Connect timeout occurred

    VM 作为ORACLE 服务器,客户端登陆提示超时,本地连接使用网络连接正常. D:>sqlplus system/oracle123@//192.168.63.121:15021/pdb01 ...