TCP

来自智得网
跳转至: 导航、​ 搜索

简介

OSI 7层模型及TCP IP模型

TCP/IP协议位于网络ISO的七层模型中的第四层,是一个面向链接的协议。

传输控制协议(TCP,Transmission Control Protocol)是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。

互联网络与单个网络有很大的不同,因为互联网络的不同部分可能有截然不同的拓扑结构、带宽、延迟、数据包大小和其他参数。TCP的设计目标是能够动态地适应互联网络的这些特性,而且具备面对各种故障时的健壮性。

不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。

应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元(MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。

每台支持TCP的机器都有一个TCP传输实体。TCP实体可以是一个库过程、一个用户进程,或者内核的一部分。在所有这些情形下,它管理TCP流,以及与IP层之间的接口。TCP传输实体接受本地进程的用户数据流,将它们分割成不超过64KB(实际上去掉IP和TCP头,通常不超过1460数据字节)的分段,每个分段以单独的IP数据报形式发送。当包含TCP数据的数据报到达一台机器时,它们被递交给TCP传输实体,TCP传输实体重构出原始的字节流。为简化起见,我们有时候仅仅用“TCP”来代表TCP传输实体(一段软件)或者TCP协议(一组规则)。根据上下文语义你应该能很消楚地推断出其实际含义。例如,在“用户将数据交给TCP”这句话中,很显然这里指的是TCP传输实体。

IP层并不保证数据报一定被正确地递交到接收方,也不指示数据报的发送速度有多快。正是TCP负责既要足够快地发送数据报,以便使用网络容量,但又不能引起网络拥塞:而且,TCP超时后,要重传没有递交的数据报。即使被正确递交的数据报,也可能存在错序的问题,这也是TCP的责任,它必须把接收到的数据报重新装配成正确的顺序。简而言之,TCP必须提供可靠性的良好性能,这正是大多数用户所期望的而IP又没有提供的功能。

原理

TCP的机制一部分体现在其报文结构中,例如序列号,窗口字段,校验和等字段等保证了TCP通信的可靠性。

报文结构

TCP协议报文结构

TCP报文的字段如下:

字段 字节数 名词解释
源端口 16 请求发起端的端口号
目的端口 16 请求目的端的段口号
序号 32 TCP对数据进行拆包的时候为每一个报文赋值了一个序列化,即该报文的第一个字节序号。

序号对于TCP传输过程中的有序性保障有重要的意义,接收端通过这个序号确认数据的完整性和次序。

确认号 32 确认号是期望对端的下一个报文段数据的第一个字节的序号
数据偏移 4 数据偏移指数据包在整个TCP报文中的位置,这个值其实也就是TCP头部的长度。

数据偏移的单位是4字节,该值*4就是TCP头部的长度。

保留字段 6 保留使用
控制位 6 每一位代表一种控制类型,这些控制位可以控制TCP状态机,分别是

紧急URG、确认ACK、推送PSH、复位RST、同步SYN、终止FIN等。

窗口字段 16 控制对方发送的数据量,用于流量控制。单位为字节。
校验和字段 16 TCP校验和是针对首部和数据两部分的。
紧急指针字段 16 本报文段中的紧急数据的最后一个字节的序号。

连接

TCP交互以及状态机

TCP所谓的"连接"是一个逻辑概念,指的是通讯双方维护的一个"连接状态",而非实际的物理连接,一个连接由一个四元组唯一确定。四元组是指(发送端IP,发送端端口,接收端IP,接收端端口)。

因为TCP连接的双工特性,TCP连接建立的过程中需要3次握手,而断开连接需要4次挥手。

三次握手的流程如下:

  • 第一次握手:客户端向服务端发起连接请求,客户端随机生成一个起始序列号ISN1,那客户端向服务端发送的报文段包含SYN标志位(也就是SYN=1),序列号seq=ISN1。
  • 第二次握手:服务端收到客户端发过来的报文后,发现SYN=1,知道这是一个连接请求,于是将客户端的起始序列号ISN保存起来,并且随机生成一个服务端的起始序列号(比如是ISN2)。然后给客户端回复一段报文,回复报文包含SYN和ACK标志(也就是SYN=1,ACK=1)、序列号seq=ISN2、确认号ack=ISN1+1。
第二次握手时如果服务端发给客户端的确认报文丢失,客户端一直没收到服务端的确认报文,客户端不确认服务端是否准备好建立该次链接,所以至少需要三次握手,第三次握手报文即使丢失,因为两次握手之后,已经明确建立流程的流程,就可以发起重试。
  • 第三次握手:客户端收到服务端的回复后发现ACK=1并且ack=ISN1+1,于是知道服务端已经收到了序列号为ISN1的报文;同时发现SYN=1,知道了服务端同意该次连接,于是就将服务端的序列号ISN2给存下来。然后客户端再回复一段报文给服务端,报文包含ACK标志位(ACK=1)、ack=ISN2+1、seq=ISN1+1。当服务端收到这个报文就能明确客户端已经收到自己的握手报文,并且同意和服务端建立连接,之后客户端和服务端就确定了本次连接。

因为TCP是全双工的,所以,发送方和接收方都需要Fin和Ack,其中一方是被动的,所以看上去就有四次挥手。四次挥手的流程:

  • 第一次挥手:当客户端的数据都传输完成后,客户端向服务端发出连接FIN报文,此后客户端将不再发送数据,但是依然可以接收数据。
  • 第二次挥手:服务端确认客户端的FIN报文,并且发送ACK,此时服务端处于关闭等待状态,因为服务端可能还有待发送数据,直到数据发送完成服务端才会发起FIN报文。
  • 第三次挥手:服务端将最后数据发送完毕后就向客户端发出连接释放报文,报文包含FIN和ACK标志位。
  • 第四次挥手:客户端收到服务端发的FIN报文后,向服务端发出确认报文,但是因为服务端最后发送的数据客户端还未完整接收,所以需要等待2MSL(最长报文寿命)后才释放TCP连接。

可靠性

TCP提供了检验和、序列号/确认应答机制、超时重传机制、最大消息长度、滑动窗口控制等方法实现了可靠性传输。

方法 实现原理 解决问题
校验和 计算TCP报文的校验和和包头中的值进行比对。 篡改包,错包
序列号/确认应答机制 发送端未收到接收端的应答数据会进行重发。 数据完整性
重传机制 重传可以分为超时重传和快速重传。

超时重传是指发送出去的数据包到接收到确认包的过程中超出超时时间导致的发送端重传; 超时重传需要等待超时间隔,效率较差,快速重传机制改用数据驱动的方式触发重传场景, 数据接收端会ACK连续收到的序列号,例如发送方需要发送1,2,3,4,5个报文, 接收方收到第1个报文ACK回复2,报文2因为某些原因未被接收端收到,接收方收到报文3、4、5,仍然回复ACK 2, 当收到3次ACK=2的报文,接收方就会重发报文2。

数据完整性
拥塞控制 TCP数据传送的过程中,如果发送频率过高或者有较多的重试,会引发网络拥塞。拥塞窗口引入了发送端和接收端的协商机制解决该问题。

发送开始定义拥塞窗口大小为1,每次收到一个ACK应答,拥塞窗口加1;而每次发送数据时,发送窗口取拥塞窗口与接送端接收窗口较小者。

慢启动:在启动初期窗口大小以指数增长方式增长,当以指数增长达到一定阈值时就停止指数增长,按照线性增长方式增加至拥塞窗口;

线性增长达到网络拥塞时立即把拥塞窗口置回1,进行新一轮的“慢启动”,同时新一轮的阈值变为原来的一半。

网络阻塞