工业网站模板,wordpress文字围绕图片,网站优化外包公司,2021最火电商平台原文#xff1a;http://blog.csdn.net/wangpengqi/article/details/17245349 这就有个细节#xff0c;一次http请求#xff0c;谁会先断开TCP连接#xff1f;什么情况下客户端先断#xff0c;什么情况下服务端先断#xff1f; 百度后#xff0c;找到原因#xff0c;主要…原文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长度的确定 对于http1.0协议来说如果响应头中有content-length头则以content-length的长度就可以知道body的长度了客户端在接收body时就可以依照这个长度来接收数据接收完后就表示这个请求完成了。而如果没有content-length头则客户端会一直接收数据直到服务端主动断开连接才表示body接收完了。而对于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消息到达发出延时段的主机时因为该主机也没有记录连接的任何信息所以它也丢弃该段。然而如果两个相同主机之间又建立了一个具有相同端口号的新连接那么离群的段就可能被看成是新连接的如果离群的段中数据的任何序列号恰恰在新连接的当前接收窗口中数据就会被重新接收其结果就是破坏新连接转载于:https://www.cnblogs.com/oxspirt/p/6054931.html