🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## TCP **TCP**(Transmission Control Protocol 传输控制协议)**是一种 面向连接的、可靠的、基于字节流的传输层通信协议**,由 IETF 的 RFC 793 定义。在简化的计算机网络 OSI 模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内 另一个重要的传输协议。 在因特网协议族(Internet protocol suite)中,TCP层是位于 IP 层之上,应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是 IP 层不提供这样的流机制,而是提供不可靠的包交换。 应用层向 TCP 层发送用于网间传输的、用 8 位字节表示的数据流,然后 TCP 把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元( MTU)的限制)。之后 TCP 把结果包传给 IP 层,由它来通过网络将包传送给接收端实体的 TCP 层。TCP 为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP 用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。 ## 三次握手 TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出 SYN 连接请求后,等待对方回答 SYN+ACK ,并最终对对方的 SYN 执行 ACK 确认。这种建立连接的方法可以防止产生错误的连接,TCP使用的流量控制协议是可变大小的滑动窗口协议 :-: ![](https://img.kancloud.cn/80/c3/80c39a5c74af82b04052491b15d2431a_882x559.png) 1. 客户端发送 **SYN(SEQ=x)**报文给服务器端,进入**SYN_SEND** 状态。 2. 服务器端收到 **SYN** 报文,回应一个 **SYN (SEQ=y)ACK(ACK=x+1)**报文,进入 **SYN_RECV** 状态。 3. 客户端收到服务器端的 **SYN** 报文,回应一个 **ACK(ACK=y+1)**报文,进入 **Established** 状态。 ## 连接成功 连接成功之后双方即可互相传输字节流,并随时可关闭连接,传输的数据有以下特性: * 传输的数据被 TCP 分割成了最适合发送的数据块传递给 IP 协议,这个发送数据称为 **报文段** 或 **段** * TCP 作为可靠性连接,每次发送数据段,会启动一个定时器,每次接收数据段,会发送一次确认,如果定时器没有及时收到确认,则会重发数据 * TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段(希望发端超时并重发)。 * 两个应用程序通过 TCP 连接交换 8bit 字节构成的字节流。TCP 不在字节流中插入记录标识符。我们将这称为字节流服务(bytestreamservice)。如果一方的应用程序先传 10 字节,又传 20 字节,再传 50 字节,连接的另一方将无法了解发方每次发送了多少字节。只要自己的接收缓存没有塞满,TCP 接收方将有多少就收多少。一端将字节流放到 TCP 连接上,同样的字节流将出现在 TCP 连接的另一端。 ## 四次挥手 终止一个连接要经过四次挥手,这是由 TCP 的**半关闭(half-close)**造成的。具体过程如下所示。 :-: ![](https://img.kancloud.cn/1e/90/1e90adb3102eaad296a5d3a1170d01e7_928x633.png) 1. 某个应用进程首先调用 close,称该端执行“主动关闭”(active close)。该端的TCP 于是发送一个 **FIN** 分节,表示数据发送完毕。 2. 接收到这个 **FIN** 的对端执行 “被动关闭”(passive close),这个 **FIN** 由TCP 确认。 * 注意:**FIN** 的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候该应用进程接收的任何其他数据之后,因为,FIN 的接收意味着接收端应用进程在相应连接上再无额外数据可接收。 3. 一段时间后,接收到这个文件结束符的应用进程将调用 close 关闭它的套接字。这导致它的 TCP 也发送一个 **FIN**。 4. 接收这个最终 **FIN** 的原发送端 TCP(即执行主动关闭的那一端)确认这个**FIN**。 既然每个方向都需要一个 **FIN** 和一个**ACK**,因此通常需要4个分节。 >“通常”是指,某些情况下,步骤1的FIN随数据一起发送,另外,步骤2和步骤3发送的分节都出自执行被动关闭那一端,有可能被合并成一个分节。 在步骤2与步骤3之间,从执行被动关闭一端到执行主动关闭一端流动数据是可能的,这称为“半关闭”(half-close)。 当一个Unix进程无论自愿地(调用exit或从main函数返回)还是非自愿地(收到一个终止本进程的信号)终止时,所有打开的描述符都被关闭,这也导致仍然打开的任何TCP连接上也发出一个FIN。 无论是客户还是服务器,任何一端都可以执行主动关闭。通常情况是,客户执行主动关闭,但是某些协议,例如,HTTP/1.0却由服务器执行主动关闭。