# 【NO.351】TCP通信过程详解以及tcp长连接和短连接

## **1. TCP连接**

当网络通信时采用TCP协议时，在真正的读写操作之前，server与client之间必须建立一个连接，当读写操作完成后，双方不再需要这个连接 时它们可以释放这个连接，连接的建立是需要三次握手的，而释放则需要4次挥手，所以说每个连接的建立都是需要资源消耗和时间消耗的

经典的三次握手示意图： 

![img](https://pic1.zhimg.com/80/v2-962ac7137ec361006e7712449ede2a00_720w.webp)



经典的四次挥手图： 

![img](https://pic4.zhimg.com/80/v2-9a7535774ab3f2cd3388c67d341f6fcb_720w.webp)



tcp的十种状态图： 

![img](https://pic1.zhimg.com/80/v2-548450728f841a0d593ab683d7065b58_720w.webp)



注意:

当一端收到一个FIN，内核让read返回0来通知应用层另一端已经终止了向本端的数据传送； 
发送FIN通常是应用层对socket进行关闭的结果。

tcp的2MSL问题 

![img](https://pic1.zhimg.com/80/v2-97667acaa84a37f46e7ebdab75648ac4_720w.webp)



## **2. TCP短连接**

我们模拟一下TCP短连接的情况，client向server发起连接请求，server接到请求，然后双方建立连接。client向server 发送消息，server回应client，然后一次读写就完成了，这时候双方任何一个都可以发起close操作，不过一般都是client先发起 close操作。为什么呢，一般的server不会回复完client后立即关闭连接的，当然不排除有特殊的情况。从上面的描述看，短连接一般只会在 client/server间传递一次读写操作

短连接的优点是：管理起来比较简单，存在的连接都是有用的连接，不需要额外的控制手段

## **3.TCP长连接**

接下来我们再模拟一下长连接的情况，client向server发起连接，server接受client连接，双方建立连接。Client与server完成一次读写之后，它们之间的连接并不会主动关闭，后续的读写操作会继续使用这个连接。

首先说一下TCP/IP详解上讲到的TCP保活功能，保活功能主要为服务器应用提供，服务器应用希望知道客户主机是否崩溃，从而可以代表客户使用资 源。如果客户已经消失，使得服务器上保留一个半开放的连接，而服务器又在等待来自客户端的数据，则服务器将应远等待客户端的数据，保活功能就是试图在服务 器端检测到这种半开放的连接。

如果一个给定的连接在两小时内没有任何的动作，则服务器就向客户发一个探测报文段，客户主机必须处于以下4个状态之一：

客户主机依然正常运行，并从服务器可达。客户的TCP响应正常，而服务器也知道对方是正常的，服务器在两小时后将保活定时器复位。 
客户主机已经崩溃，并且关闭或者正在重新启动。在任何一种情况下，客户的TCP都没有响应。服务端将不能收到对探测的响应，并在75秒后超时。服务器总共发送10个这样的探测 ，每个间隔75秒。如果服务器没有收到一个响应，它就认为客户主机已经关闭并终止连接。 
客户主机崩溃并已经重新启动。服务器将收到一个对其保活探测的响应，这个响应是一个复位，使得服务器终止这个连接。 
客户机正常运行，但是服务器不可达，这种情况与2类似，TCP能发现的就是没有收到探查的响应。 
从上面可以看出，TCP保活功能主要为探测长连接的存活状况，不过这里存在一个问题，存活功能的探测周期太长，还有就是它只是探测TCP连接的存活，属于比较斯文的做法，遇到恶意的连接时，保活功能就不够使了。

在长连接的应用场景下，client端一般不会主动关闭它们之间的连接，Client与server之间的连接如果一直不关闭的话，会存在一个问 题，随着客户端连接越来越多，server早晚有扛不住的时候，这时候server端需要采取一些策略，如关闭一些长时间没有读写事件发生的连接，这样可 以避免一些恶意连接导致server端服务受损；如果条件再允许就可以以客户端机器为颗粒度，限制每个客户端的最大长连接数，这样可以完全避免某个蛋疼的 客户端连累后端服务。

长连接和短连接的产生在于client和server采取的关闭策略，具体的应用场景采用具体的策略，没有十全十美的选择，只有合适的选择。

**什么是“长连接”和“短连接”？**

解释1

所谓长连接指建立SOCKET连接后不管是否使用都保持连接，但安全性较差；

所谓短连接指建立SOCKET连接后发送后接收完数据后马上断开连接，一般银行都使用短连接

解释2

长连接就是指在基于tcp的通讯中，一直保持连接，不管当前是否发送或者接收数据。

而短连接就是只有在有数据传输的时候才进行连接，客户－服务器通信/传输数据完毕就关闭连接。

解释3

长连接和短连接这个概念好像只有移动的CMPP协议中提到了，其他的地方没有看到过。 
通信方式 
各网元之间共有两种连接方式：长连接和短连接。所谓长连接，指在一个TCP连接上可以连续发送多个数据包，在TCP连接保持期间，如果没有数据包发送，需要双方发检测包以维持此连接。短连接是指通信双方有数据交互时，就建立一个TCP连接，数据发送完成后，则断开此TCP连接，即每次TCP连接只完成一对 CMPP消息的发送。 
现阶段，要求ISMG之间必须采用长连接的通信方式，建议SP与ISMG之间采用长连接的通信方式。

解释4

短连接：比如http的，只是连接、请求、关闭，过程时间较短,服务器若是一段时间内没有收到请求即可关闭连接。 
长连接：有些服务需要长时间连接到服务器，比如CMPP，一般需要自己做在线维持。

**HTTP协议之长、短连接**

一、长连接与短连接：

长连接：client方与server方先建立连接，连接建立后不断开，然后再进行报文发送和接收。 
这种方式下由于通讯连接一直存在。此种方式常用于P2P通信。 
短连接：Client方与server每进行一次报文收发交易时才进行通讯连接，交易完毕后立即断开连接。 
此方式常用于一点对多点通讯。C/S通信。 
二、长连接与短连接的操作过程：

短连接的操作步骤是： 
建立连接——数据传输——关闭连接…建立连接——数据传输——关闭连接 
长连接的操作步骤是： 
建立连接——数据传输…（保持连接）…数据传输——关闭连接 
三、长连接与短连接的使用时机：

长连接：长连接多用于操作频繁，点对点的通讯，而且连接数不能太多的情况。 
每个TCP连接的建立都需要三次握手，每个TCP连接的断开要四次握手。 
如果每次操作都要建立连接然后再操作的话处理速度会降低，所以每次操作后，下次操作时直接发送数据就可以了，不用再建立TCP连接。例如：数据库的连接用长连接，如果用短连接频繁的通信会造成socket错误，频繁的socket创建也是对资源的浪费。 
短连接：web网站的http服务一般都用短连接。因为长连接对于服务器来说要耗费一定的资源。像web网站这么频繁的成千上万甚至上亿客户端的连接用短连接更省一些资源。试想如果都用长连接，而且同时用成千上万的用户，每个用户都占有一个连接的话，可想而知服务器的压力有多大。所以并发量大，但是每个用户又不需频繁操作的情况下需要短连接。总之：长连接和短连接的选择要根据需求而定。 
四、发送接收方式：

1、异步：报文发送和接收是分开的，相互独立，互不影响的。这种方式又分两种情况： 
异步双工：接收和发送在同一个程序中，有两个不同的子进程分别负责发送和接送。 
异步单工：接送和发送使用两个不同的程序来完成。 
2、同步：报文发送和接收是同步进行，即报文发送后等待接送返回报文。同步方式一般需要考虑超时问题，试想我们发送报文以后也不能无限等待啊，所以我们要设定一个等待 
时候。超过等待时间发送方不再等待读返回报文。直接通知超时返回。 
五、报文格式：

通信报文格式多样性更多，相应地就必须设计对应的读写报文的接收和发送报文函数。 
阻塞与非阻塞方式

1、非阻塞方式：读函数不停的进行读动作，如果没有报文接收到，等待一段时间后超时返回，这种情况一般需要指定超时时间。 
2、阻塞方式：如果没有接收到报文，则读函数一直处于等待状态，知道报文到达。 
循环读写方式

1、一次直接读写报文：在一次接收或发送报文动作中一次性不加分别地全部读取或全部发送报文字节。 
2、不指定长度循环读写：这一版发生在短连接进程中，受网络路由等限制，一次较长的报文可能在网络传输过程中被分解成很多个包，一次读取可能不能全部读完一次报文，这就需要循环读取报文，直到读完为止。 
3、带长度报文头循环读写：这种情况一般在长连接中，由于在长连接中没有条件能够判断循环读写什么时候结束。必须要加长度报文头。读函数先是读取报文头的长度，再根据这个长度去读报文，实际情况中，报头码制格式还经常不一样，如果是非ASCII的报文头，还必须转换成ASCII常见的报文头编制有： 
1、n个字节的ASCII码。 
2、n个字节的BCD码。 
3、n个字节的网络整型码。 
以上是几种比较典型的读写报文方式，可以与通信方式模板一起预先提供一些典型的API读写函数。当然在实际问题中，可能还必须编写与对方报文格式配套的读写API. 在实际情况中，往往需要把我们自己的系统与别人的系统进行连接， 有了以上模板与API,可以说连接任何方式的通信程序都不存在问题。

**什么时候用长连接，短连接？**

长连接多用于操作频繁，点对点的通讯，而且连接数不能太多情况，。每个TCP连接都需要三步握手，这需要时间，如果每个操作都是先连接，再操作的话那么处理速度会降低很多，所以每个操作完后都不断开，次处理时直接发送数据包就OK了，不用建立TCP连接。例如：数据库的连接用长连接， 如果用短连接频繁的通信会造成socket错误，而且频繁的socket 创建也是对资源的浪费。

而像WEB网站的http服务一般都用短链接，因为长连接对于服务端来说会耗费一定的资源，而像WEB网站这么频繁的成千上万甚至上亿客户端的 连接用短连接会更省一些资源，如果用长连接，而且同时有成千上万的用户，如果每个用户都占用一个连接的话，那可想而知吧。所以并发量大，但每个用户无需频 繁操作情况下需用短连好。 
总之，长连接和短连接的选择要视情况而定。

原文地址：https://zhuanlan.zhihu.com/p/165977927

作者：linux