TCP协议
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的协议,提供了可靠的数据传输服务,通过序列号、确认机制、重传等机制实现数据的顺序和完整性。应用层很多通信协议都基于TCP进行传输,比如HTTP、MQTT等。
TCP协议源文档
TCP通信特点
- 面向连接通信
- 可靠通信方式
- 面向字节流
- 在网络状况不佳的时候尽量降低系统由于重传带来的带宽开销
- 通信连接维护是面向通信的两个端点的,而不考虑中间网段和节点
为了满足上述特点,TCP协议作了以下规定
①数据分片:在发送端对用户数据进行分片,在接收端进行重组,由TCP确定分片的大小并控制分片和重组。
②到达确认:接收端接收到分片数据时,根据分片数据序号向发送端发送一个确认。
③超时重发:发送方在发送分片时启动超时定时器,如果在定时器超时之后没有收到相应的确认,重发分片。
④滑动窗口:TCP连接每一方的接收缓冲空间大小都固定,接收端只允许另一端发送接收端缓冲区所能接纳的数据,TCP在滑动窗口的基础上提供流量控制,防止较快主机致使较慢主机的缓冲区溢出。
⑤失序处理:作为IP数据报来传输的TCP分片到达时可能会失序,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。
⑥重复处理:作为IP数据报来传输的TCP分片会发生重复,TCP的接收端必须丢弃重复的数据。
⑦数据校验:TCP将保持它首部和数据的检验和,这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到分片的检验和有差错,TCP将丢弃这个分片,并不确认收到此报文段导致对端超时并重发。
TCP技术概念
MTU:Maximum Transmit Unit,最大传输单元,即物理接口(数据链路层)提供给其上层(通常是IP层)最大一次传输数据的大小,以普遍使用的
以太网为例,缺省MTU=1500 Byte,这是以太网接口对IP层的约束,如果IP层有<=1500 Byte需要发送,只需要一个IP包就可以完成发送任务,如果IP层有>=1500 Byte数据需要发送,需要分片才能完成发送,这些分片有一个共同点,即IP Header ID相同
MSS:Maximum Segment Size,TCP提交给IP层最大分段大小,不包含TCP Header和TCP Option,只包含TCP Payload,MSS是TCP用来限制application层最大的发送字节数,如果底层物理接口MTU=1500 Byte,则MSS=1500-20(IP Header)-20(TCP Header)=1460 Byte(MSS),如果application有2000 Byte发送,则需要两个Segment才可以完成发送,第一个TCP Segment=1460,第二个TCP Segment=540
RTO:Retransmission Time Out,重传超时时间,TCP超时与重传中一个很重要的部分是对一个给定连接的往返时间(RTT)的测量,由于网络流量的变化,这个时间会相应地发生改变,TCP需要跟踪这些变化并动态调整超时时间RTO
RTT:Round Trip Time,一个连接的往返时间,即数据发送时刻到接收到确认的时刻的差值,由三部分组成:链路的传播时间,接收端的处理时间,返回到发送端的时间
MSL:Maximum Segment Lifetime,指明TCP报文在Internet上最长生存时间,每个具体的TCP实现都必须选择一个确认的MSL值。建议是2分钟。
拥塞窗口:拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口。如果再考虑到接收方的接收能力,那么发送窗口还可能小于拥塞窗口。发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去。但只要网络出现拥塞,拥塞窗口就减少一些,以减少注入到网络中的分组数
滑动窗口:一个TCP连接发送端在某个时刻能发多少数据是由滑动窗口控制的,而滑动窗口的大小实际上是由两个窗口共同决定的,一个是接收端的通告窗口,也就是TCP头部中的Window Size,会随着ACK报文发送给发送端,发送端必须保证发送的数据不超过这个剩余的空间以免造成缓冲区溢出。另一个窗口是发送端的拥塞窗口。滑动窗口的大小就是通告窗口和拥塞窗口的较小值。
慢启动:在拥塞窗口大小指数增大到一定程度后,遇到网络拥塞会造成丢包,一旦出现此类问题,拥塞窗口就会迅速减小,以便网络能够缓过来。
拥塞避免:在拥塞窗口达到一定程度后,减慢增大的速度,从指数增大改变为线性增大。
TCP定时器
连接建立定时器:connection-establishment timer,连接请求发送后启动,75秒内没有得到确认则会关闭连接。
重传定时器:retransmission timer,在TCP发送数据后启动,超时后没有得到确认的数据将会被重传,定时器重新启动。定时器取值根据重传次数和RTT时间动态变化,取值范围在1~64秒之间。若定时器13次超时后仍得不到确认,连接将被终止。
延迟应答定时器:delayed ACK timer,在用户数据量少且次数多的情况下(等数据发完后一起确认,减少网络开销),在TCP收到需要确认,但可以延迟确认的数据后启动。取值为200ms,如果200ms内有数据发送,则随数据一起发送,否则在200ms后单独发送。
坚持定时器:persist timer,在对端Window Size为0时启动,在定时器超时后发送一字节数据的报文探测对端接收缓存是否有空间(Window Szie不为0)。坚持定时器采用退避算法取值,取值范围在5~64秒之间。
保活定时器:keepalive timer,在连接长时间空闲时启动,在空闲2小时后会超时并且发送探测报文,判断对端是否存在,超时后会重启并取值75秒,如果超过8次后仍未得到确认,则连接被终止。
FIN_WAIT_2定时器:FIN_WAIT_2 timer,在进入FIN_WAIT_2状态后启动,退出FIN_WAIT_2状态后停止。FIN_WAIT_2定时器第一次取值10分钟,超时重启,取值75秒,再次超时后强行终止连接。
TIME_WAIT定时器:TIME_WAIT timer or 2MSL timer,在进入TIME_WAIT状态启动,取值为2MSL(最大值)。
TCP头部报文
TCP头部大小为20个字节(不包含任何TCP选项)
(1)TCP端口号
包括源端口号和目标端口号,大小为各2个字节
- 源端口号:source port,发送方端口号。
- 目标端口号:destination port,接收方端口号。
(2)TCP序列号
Sequence Number,保证TCP传输数据的顺序性。序号标识了从TCP发送端到TCP接收端单向发送的数据字节流(同一时间两个方向的序号不一定相同),TCP用序号对每个字节进行计数,比如现在序列号为1000,发送了1000,下一个序列号就是2000。序号是一个32位的无符号数,达到最大值后会重新从0开始。
(3)TCP确认号
Acknowledgment Number,保证TCP传输数据的可靠性。确认号用于响应TCP报文。
(4)TCP头部大小
Header Length,大小为4位,单位为4个字节。因此,TCP头部大小范围为20~60(15*4)个字节,没有任何选项字段的TCP头部长度为20字节,最多可以有60个字节的TCP头部。
(5)TCP预留位
Reserved,预留位,数据都为0,大小为4位。
(6)TCP控制位
- CWR:Congestion window reduced,拥塞窗口减少。拥塞窗口减少标志被发送主机设置,用来表明它接收到了设置ECE标志的TCP包。拥塞窗口是被TCP维护的一个内部变量,用来管理发送窗口大小。
- ECE:ECN-Echo,显式拥塞提醒回应。当一个IP包的ECN域被路由器设置为11时,接收端而非发送端被通知路径上发生了拥塞。ECN使用TCP头部来告知发送端网络正在经历拥塞,并且告知接收端发送段已经受到了接收端发来的拥塞通告,已经降低了发送速率。
- URG:Urgent Pointer field significant,紧急位,当URG=1时,表示此报文段中有紧急数,是高优先级的数据,应尽快传送,不用再缓存里排队,配合紧急指针使用。
- ACK:Acknowledgment fieldsignificant,确认位,当ACK=1时,表示确认号有效,TCP就是根据ACK号来告知对方是否收到了消息。
- PSH:Push Function,推送位,当PSH=1时,表示接接收方得到后就可直接送到应用程序,而不必等到缓冲区满时才传送。
- RST:Reset the connection,重置位,当RST=1时,表示TCP连接出现了严重错误(心跳包超时,连接超时等),必须释放连接,然后再重新建立传输连接。
- SYN:Synchronize sequence numbers,同步位,当SYN=1时,表示是一个连接请求/连接请求接收报文。
- FIN:No more data from sender,终止位,当FIN=1时,表示此报文发送方数据已发送完毕,要求释放连接。
(7)TCP窗口大小
Window size,指发送该报文时接收缓冲区的空闲空间大小,因此是动态的,主要用于进行流量控制,解决流控拥塞问题。总共占2个字节。
(8)TCP校验和
TCP Checksum,对整个TCP报文段,即TCP头部和TCP数据进行校验和计算,并由目标端进行验证。TCP的校验方法和IP相同-算数和求补,不同的是IP只校验报文头部,TCP校验整个报文。总共占2个字节。
(9)TCP紧急数据指针
Urgent Pointer,只有当URG标志为1时才有效,紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。
(10)TCP选型
TCP连接
三次握手(建立连接)
第一次握手:客户端给服务端发送建立TCP连接的请求报文,报文中SYN同部位置1,表示这是一个建立连接报文。报文中seq序列号是随机生成的整数。同时客户端进入同步已发送状态(SYN-SENT)。
第二次握手:服务端返回请求应答报文,报文中SYN同部位置1,表示这是一个建立连接报文。报文中seq序列号是随机生成的整数。报文中ack为请求报文的seq+1,表示对请求已经收到。同时服务端进入同步已接收状态(SYN-RCVD)。同时客户端进入连接已建立状态(ESTABLISHED)。
第三次握手:客户端对服务端的回复发送应答报文,报文中SYN同部位置1,表示这是一个建立连接报文。报文中seq是请求报文的seq+1,表示对哪次连接请求的确认。报文中ack为服务端请求应答报文的seq加1,表示收到服务器的应答对确认连接的建立。同时服务端进入连接已建立状态(ESTABLISHED)。
四次挥手(释放连接)
第一次挥手:客户端给服务端发送释放连接的请求报文,报文中FIN终止位置1,表示这个一个释放连接报文。报文中的seq和ack在前面数据交互的基础上+1。同时客户端进入FIN_WAIT_1状态。
第二次挥手:服务端给客户端返回释放应答报文,报文中FIN终止位置1,表示这个一个释放连接报文。报文中ack为释放请求报文的seq+1,表示收到释放连接请求。同时服务端进入CLOST_WAIT状态。客户端进入FIN_WAIT_2状态。
第三次挥手:服务端等待一段时间,以处理客户端发过来的数据后,发送释放报文给客户端,报文中FIN终止位置1。seq为释放报文的ack值。同时服务端进入LAST_ACK状态。
第四次挥手:客户端收到服务端发送的FIN报文后,向服务端发送ACK报文作为确认,ack为FIN报文seq+1。同时客户端进入TIME_WAIT状态。服务器端接收到ACK报文后会变成CLOSED状态,客户端等待一段时间后,如果服务端没有数据返回,也会变成CLOSED状态
连接状态
LISTEN:监听状态,服务端状态,等待客户端TCP 连接请求。
SYN_SENT:发送完一个连接请求后等待一个匹配的连接请求。如果75秒内得不到确认,连接将被关闭。
SYN_RECEIVED:发送连接请求并且接收到后等待连接请求确认。
ESTABLISHED:表示一个打开的连接,连接的数据传输阶段的正常状态。
FIN_WAIT_1:等待对端TCP 的连接终止请求,或者等待之前发送的连接终止请求的确认。
FIN_WAIT_2:等待对端TCP 的连接终止请求。
CLOSE_WAIT:等待的连接终止请求。
LAST_ACK:等待先前发送给对端TCP 的连接终止请求的确认
TIME_WAIT:等待以确保对端TCP 接收到它的连接终止请求的确认。
学习笔记,有问题欢迎指出