传输控制协议(TCP,TransmissionControl Protocol)是一种面向连接的、可靠的、基于字节流的
传输层通信协议,由
IETF的RFC 793定义。
定义
传输控制协议(TCP,Transmission Control Protocol)是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。
互联网络中的不同部分可能有截然不同的拓扑结构、带宽、延迟、数据包大小和其它参数,而TCP的设计目标是能够动态地适应互联网络的这些特性,以及具备面对各种故障时的健壮性。
不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层无法提供这样的流机制,而是提供了不可靠的包交换机制。
应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分成适当长度的报文(通常受该计算机连接的网络的数据链路层的最大传输单元(MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,给每个包分配了一个序号,同时,这些序号也可以保证传送到接收端实体的包的按序接收。然后接收端实体对每个已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失,并将会被重传。TCP用一个校验和函数来检验收到的数据包是否有传输错误;一个数据包在发送和接收时都要校验和计算和验证。
每台支持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的正式定义由IETF(互联网工程任务组)于1981年9月的RFC793给出。随着时间的推移,IETF已经对其做了许多改进,各种错误和不一致的地方逐渐被修复。
发展历程
RFC 793plus澄清了说明
RFC 1122 修复了bug
RFC 1323 对TCP做了高性能扩展
RFC 2018定义了TCP的选择性确认
RFC 2581定义了TCP的拥塞控制
RFC 2873定义了为服务质量而重用的头字段
RFC 2988改进了TCP的重传计时器
RFC 3168 定义了TCP的显式拥塞通知
RFC 6093 实现了TCP的紧急机制
RFC 6528 指定了用于防范初试序列号攻击的算法
RFC 6691 提出一种TCP选项和最大段大小的建议
重⼤节点
完整的TCP协议集很大,因而IETF专门发布了一个针对许多RFC的指南,它就是作为另一个RFC文档公布的RFC4614。
阶段性成果
RFC 9293 把过去四十几年针对TCP协议的各种修补全部合订到了一起,一次性地替代了RFC 879、RFC 2873、RFC6093、RFC 6429、RFC 6528、RFC 6691和主体RFC 793, 此外整体替换了RFC 1122中关于 TCP 的全部内容。
基本原理
主要技术
当应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,TCP则把数据流分割成适当长度的报文,最大传输段大小(MSS)通常受该计算机连接的网络的数据链路层的最大传送单元(MTU)限制。之后TCP把数据包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。
TCP为了保证可靠报文传输,给每个包分配了一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的包(假设丢失了)将会被重传。
在数据正确性与合法性上,TCP用一个校验和函数来检验数据是否有传输错误,在发送和接收时都要计算校验和;同时可以使用md5认证对数据进行加密。
在可靠传输方面,采用了超时重传和捎带确认机制。
在流量控制方面,采用了滑动窗口协议,协议中规定,对于窗口内未经确认的分组需要重传。
在拥塞控制方面,采用了广受好评的TCP拥塞控制算法(也称AIMD算法)。
拥塞控制
TCP拥塞控制算法主要包括四个主要部分:
(1)慢启动
每当建立一个TCP连接时或一个TCP连接发生超时重传后,该连接便进入慢启动阶段。进入慢启动后,TCP实体将拥塞窗口的大小初始化为一个报文,即:cwnd=1。此后,每收到一个报文的确认(ACK),cwnd值加1,即拥塞窗口指数增加。当cwnd值超过慢启动阈值(ssthresh)或发生报文丢失重传时,慢启动阶段结束。前者进入拥塞避免阶段,后者重新进入慢启动阶段。
(2)拥塞避免
在慢启动阶段,当cwnd值超过慢启动阈值(ssthresh)后,慢启动过程结束,TCP连接进入拥塞避免阶段。在拥塞避免阶段,每次发送cwnd个报文被完全确认后,才将cwnd值加1。在此阶段,cwnd值线性增加。
(3)快速重传
快速重传是对超时重传的改进。当源端收到对同一个报文的三个重复确认时,就可以确定该报文已经丢失,因此立刻重传丢失的报文,而不必等到重传定时器(RTO)超时。以此减少不必要的等待时间。
(4)快速恢复
快速恢复是对丢失恢复机制的改进。在快速重传之后,不经过慢启动过程而直接进入拥塞避免阶段。每当快速重传后,置ssthresh=cwnd/2、cwnd=ssthresh+3。此后,每收到一个重复确认,将cwnd值加1,直至收到对丢失报文和其后若干报文的累积确认后,置cwnd=ssthresh,此后进入拥塞避免阶段。
技术特点
TCP是一种面向广域网的通信协议,目的是在跨越多个网络通信时,为两个通信端点之间提供一条具有下列特点的通信方式:
(1)基于流的方式;
(2)面向连接;
(3)可靠通信方式;
(4)在网络状况不佳的时候尽量降低系统由于重传带来的带宽开销;
(5)通信连接维护是面向通信的两个端点的,而不考虑中间网段和节点。
为满足TCP协议的这些特点,TCP协议做了如下的规定:
①数据分片:在发送端对用户数据进行分片,在接收端进行重组,由TCP确定分片的大小并控制分片和重组;
②到达确认:接收端接收到分片数据时,根据分片数据序号向发送端发送一个确认;
③超时重传:发送方在发送一个分片时启动超时定时器,如果在定时器超时之后没有收到相应的确认,重发该分片;
④滑动窗口:TCP连接每一方的接收缓冲空间大小都是固定的,接收端只允许另一端发送接收端缓冲区所能接纳的数据,TCP通过滑动窗口机制提供流量控制,防止较快主机致使较慢主机的缓冲区溢出;
⑤失序处理:作为IP数据报来传输的TCP分片到达时可能会失序,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层;
⑥重复处理:作为IP数据报来传输的TCP分片可能会发生重复传输,TCP的接收端必须丢弃重复的数据;
⑦数据校验:TCP将保持它首部和数据的检验和,这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到分片的检验和有差错,TCP将丢弃这个分片,且不确认收到此报文,从而导致发端超时并重发。
首部格式
TCP的首部格式如下图所示:
① Source Port是源端口,16位。
② Destination Port是目的端口,16位。
③ Sequence Number是发送数据包中的第一个字节的序列号,32位。
④ Acknowledgment Number是确认序列号,32位。
⑤ Data Offset是数据偏移,4位,该字段的值是TCP首部(包括选项)长度除以4。
⑥ Reserved 是保留位,4位,为将来使用而保留的一组控制位。在生成段中必须为零。
⑦ 控制位(标志位): 6位,
CWR 表示减少拥塞窗口
ECE 表示从对方到本方的网络有拥塞
URG表示Urgent Pointer字段有实际意义
ACK表示Acknowledgment Number字段有实际意义
PSH表示Push功能
RST表示复位TCP连接
SYN表示SYN报文(在建立TCP连接的时候使用)
FIN表示数据发送完毕(在关闭TCP连接的时候使用)
⑧ Window表示接收缓冲区的空闲空间,16位,用来告诉TCP连接对端自己能够接收的最大数据长度。
⑨ Checksum是校验和,16位。
⑩ Urgent Pointers是紧急指针,16位,只有URG标志位被设置时该字段才有意义,表示紧急数据相对序列号(SequenceNumber字段的值)的偏移。
工作方式
连接建立
TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答SYN+ACK,并最终对对方发来的 SYN 执行 ACK 确认。这种建立连接方法可以防止产生错误的连接,TCP使用的流量控制协议是可变大小的滑动窗口协议。
下面给出了一个在客户端与服务器端之间建立一个TCP连接的三次握手过程:
1.客户端发送SYN(SEQ=x)报文给服务器端,进入SYN_SENT状态。
2.服务器端收到SYN报文,回应一个SYN (SEQ=y)ACK(ACK=x+1)报文,进入SYN_RECV状态。
3.客户端收到服务器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态。
三次握手完成后,TCP客户端和服务器端之间就成功地建立一个TCP连接,可以开始传输数据了。
连接终止
建立一个TCP连接需要三次握手,而终止一个TCP连接要经过四次握手,这是由TCP的半关闭(half-close)造成的。具体过程如下图所示。
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)。
③当一个连接的进程无论自愿地(调用exit或从main函数返回)还是非自愿地(收到一个终止本进程的信号)终止时,所有打开的描述符都被关闭,这也导致仍然打开的任何TCP连接上也发出一个FIN。
④无论是客户端还是服务端,任何一端都可以执行主动关闭。通常情况是,客户端执行主动关闭,但是某些协议(例如HTTP/1.0)却由服务端执行主动关闭。
应用
TCP 用于在传输层有必要实现可靠传输的情况,例如以下几种应用场景:
①电子邮件: SMTP(Simple Mail Transfer Protocol)和POP3(Post Office Protocol)等电子邮件协议使用TCP进行邮件的传输和接收。
②文件传输: FTP(File Transfer Protocol)是基于TCP的文件传输协议,用于在网络上进行文件的上传和下载。
③远程登录: SSH(Secure Shell)协议使用TCP提供安全的远程登录功能,允许用户通过网络远程连接到其他计算机上。
④即时通讯: 许多即时通讯应用,如QQ、微信,使用TCP确保消息的可靠传输,防止消息的丢失或乱序。
⑤数据库访问: 数据库管理系统(如MySQL、PostgreSQL)使用TCP协议来实现客户端与服务端之间的可靠数据传输,确保数据库操作的一致性和完整性。
参考资料
RFC 793.Transmission Control Protocol.
RFC 9293.Transmission Control Protocol (TCP).
RFC 3168.The Addition of Explicit Congestion Notification (ECN) to IP.