`
m635674608
  • 浏览: 5031650 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

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

    博客分类:
  • java
 
阅读更多

我们有2台内部http服务(nginx):

201:这台服务器部署的服务是account.api.91160.com,这个服务是供前端页面调用;

202:这台服务器部署的服务是hdbs.api.91160.com,    这个服务是供前端页面调用;

 

近期发现,这2台服务器的网络连接中,TIME_WAIT 数量差别很大,201的TIME_WAIT大概20000+,202的TIME_WAIT大概1000 ,差距20倍;2台的请求量差不多,都是以上内部调用的连接,且服务模式也没有什么差异,为什么连接数会差这么大?

 

后找原因:是因为这2个模块的调用程序由不同团队写的,调用方式不一样,导致一个是调用方(客户端,PHP程序)主动断开连接,一个是被调用方(服务端 201、202)主动断开连接;因TIME_WAIT 产生在主动断开连接的一方,因此导致一台服务器TIME_WAIT 数高,一台TIME_WAIT 数低;

 

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

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

 

 以下内容转载:(http://blog.csdn.net/wangpengqi/article/details/17245349

当然,在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的数量。

 

总结: (不考虑keepalive)

http1.0  

带content-length,body长度可知,客户端在接收body时,就可以依据这个长度来接受数据。接受完毕后,就表示这个请求完毕了。客户端主动调用close进入四次挥手。

不带content-length ,body长度不可知,客户端一直接受数据,直到服务端主动断开

 

http1.1

带content-length                       body长度可知     客户端主动断开

带Transfer-encoding:chunked       body会被分成多个块,每块的开始会标识出当前块的长度,body就不需要通过content-length来指定了。但依然可以知道body的长度 客户端主动断开

不带Transfer-encoding:chunked且不带content-length        客户端接收数据,直到服务端主动断开连接。

 

即 :如果能够有办法知道服务器传来的长度,都是客户端首先断开。如果不知道就一直接收数据。知道服务端断开。

 

 

http://www.cnblogs.com/web21/p/6397525.html

分享到:
评论

相关推荐

    QT的TCP一个服务端连接多个客户端

    在本文中,我们将深入探讨如何使用QT来实现一个TCP服务器,该服务器可以同时连接并处理多个客户端的请求。 首先,我们需要了解TCP(传输控制协议)的基本原理。TCP是一种面向连接的、可靠的、基于字节流的传输层...

    tcp服务端&客户端模拟器

    TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,是互联网协议族的核心部分。TCP服务端与客户端是网络通信中的两个关键角色,它们之间的交互构成了TCP通信的基础。 在...

    TCP客户端,服务端调试工具

    为了有效地测试和调试TCP客户端与服务端的通信,开发者通常会使用专门的调试工具。本篇将详细介绍TCP客户端和服务端调试工具及其重要性,以及如何使用“网络调试助手”进行网络通信问题的排查。 TCP客户端是发起...

    C# 实现 TCP服务端+客户端 带心跳机制.zip

    服务端启动后,会持续监听指定的IP地址和端口号,当接收到客户端的连接请求时,会创建一个TcpClient对象来处理该连接。 ```csharp using System.Net; using System.Net.Sockets; TcpListener listener = new Tcp...

    基于C# Winform完成Tcp客户端与服务端、udp客户端服务端通讯工具

    3. 当有客户端连接请求时,`AcceptTcpClient()`方法会阻塞,直到连接建立。返回一个新的`TcpClient`对象,可用于读写数据。 4. 在接收数据时,通过`GetStream()`获取到`NetworkStream`,然后可以使用`StreamReader`...

    [Qt] TCP服务器客户端(可连接多个客户端,断线重联,指定格式解析))

    在本文中,我们将深入探讨如何使用Qt框架实现一个TCP服务器客户端系统,该系统具备多客户端连接、断线重连和自定义数据解析功能。首先,我们来看一下标题和描述所涉及的关键技术点。 1. **TCP服务器客户端**:TCP...

    TCP作为服务端接收来自客户端的连接

    本篇文章将详细探讨如何使用TCP作为服务端来接收来自多个客户端的连接,特别是在Visual Studio 2010环境下,结合C++语言和简单的用户界面实现这一功能。 首先,我们需要理解TCP的基本工作原理。TCP是一种面向连接的...

    TCP客户端服务端

    总结起来,"TCP客户端服务端"是一个基于MFC的TCP通信模拟工具,它涵盖了TCP服务端的监听、响应,以及TCP客户端的连接、发送和接收操作。通过这两个程序,开发者可以进行TCP通信的实践,加深对TCP协议的理解,同时也...

    TCP 客户端 服务端 网络编程

    服务端在启动时会先创建一个监听套接字,然后绑定到一个IP地址和端口号上,接着进入监听状态。当收到客户端的连接请求时,服务端会创建一个新的套接字用于与客户端通信,并继续监听新的连接请求。 **TCP网络编程**...

    TCP服务端客户端交互

    一旦客户端发起连接,服务端将接收并回应,形成一条TCP连接。 客户端通常负责发起连接并发送数据。在这个实验中,客户端程序将向服务端发送一些文本数据,例如用户输入的信息。这些数据会被封装在TCP报文中,通过...

    [线上问题] “服务端长连接与客户端短连接引起Nginx产生大量\"TIME_WAIT\"状态的线程”的问题分析解决

    本文讨论了在线上环境中,服务端长连接和客户端短连接配置不当导致Nginx服务器产生大量“TIME_WAIT”状态线程的问题,同时提供了问题的分析和解决方法。本文主要涉及的网络编程知识点包括长连接与短连接的定义和区别...

    java socket长连接客户端服务端(标准实例)

    本案例实现了基于TCP协议的Socket长连接,即客户端和服务端建立连接后,保持连接状态,进行多次数据交互而无需频繁建立和断开连接的过程。 #### 二、长连接的优点 1. **减少连接建立的时间**:由于TCP连接的建立...

    tcp通信类(包含客户端和服务端类)

    TCP是一种面向连接的协议,它在数据传输前会先建立连接,确保数据可以正确无误地发送到目的地。TCP通过三次握手建立连接,通过四次挥手断开连接。在TCP通信中,客户端和服务端的角色分工明确: 1. 客户端:发起连接...

    STM32单片机作TCP服务器,实现PC多客户端连接Demo

    5. **错误处理与连接关闭**:正确处理网络错误和客户端断开连接的情况,释放相应的资源。 在`NETCONN_TCP (UCOSIII)F750`这个文件中,我们可以找到具体的代码实现,包括UCOSIII实时操作系统对任务管理和资源调度的...

    TCP、UDP客户端服务端例程代码

    客户端会发送一个连接请求到服务器,服务器接收到请求后,同意建立连接,然后双方可以开始数据传输。一旦通信完成,双方都会执行断开连接的步骤。 `tcp_client`的代码可能包含以下关键部分: 1. 创建套接字:使用...

    TCP收发json. 客户端和服务端

    在本例中,我们将使用QT Creator来编写TCP客户端和服务端程序,实现JSON数据的收发。 TCP收发JSON数据通常涉及以下几个步骤: 1. **创建TCP套接字**:在QT中,我们可以使用`QTcpSocket`类来创建TCP套接字,用于...

    tcp服务端和客户端程序

    在Windows环境下,TCP编程主要使用套接字API,包括socket()函数创建套接字,bind()函数绑定本地地址和端口,listen()函数使服务端进入监听状态,accept()函数接收客户端连接,connect()函数用于客户端连接服务端,...

    VB TCP通信示例(服务端+客户端)

    TCP通信的基础是建立一个可靠的连接,它在数据传输前会通过三次握手建立连接,并在传输后通过四次挥手释放连接。在VB中,我们可以使用Winsock控件来实现TCP通信,这个控件提供了与网络通信相关的各种功能。 服务端...

    qt TCP多客户端通信

    QT TCP多客户端通信是网络编程中的一个重要话题,它涉及到如何使用QT库来构建一个服务器,该服务器能够同时处理来自多个客户端的TCP连接。QT是一个跨平台的C++库,提供了丰富的功能,包括图形用户界面、网络编程、...

    tcp服务端与客户端通讯.zip

    TCP是一种面向连接的协议,这意味着在数据交换之前,客户端必须先与服务器建立连接。在C#中,可以使用`System.Net.Sockets.TcpClient`和`System.Net.Sockets.TcpListener`类来实现这一过程。客户端通过`TcpClient....

Global site tag (gtag.js) - Google Analytics