ps:文中图片均来自网络,若有侵权请联系我删除
pps:本文中的观点、内容,均来自本人对TCP和对老师讲解的理解,若有错误,欢迎指出
TCP的特点
- TCP是面向连接的端到端协议,连接建立的过程为三次握手,断开连接的过程为四次挥手
- TCP不支持多播和广播
- TCP为全双工连接,同一连接上可有双向的数据流
- TCP提供可靠交付(可靠交付4个要求或者说特点:不丢、不错、不乱(按序)、不重复)
- TCP为C/S模式
- 面向字节流(应用层消息按字节编号)
- 流量控制(滑动窗口机制)
- 拥塞控制(慢启动、快恢复等,将在下文细说)
TCP报文格式
TCP由IP数据报封装。
- 序号(seq):用来标识从TCP发送端到TCP接收端发送的数据字节流,表示在这个报文段中的第一个数据字节。当仅ACK为1时,不消耗序列号(不确定)。
- 确认号(ack):发送这一端所期望收到的下一个序号。(即表示,这一端已经正确接收了ack以前的所有字节)
- 六个标志bit:
- URG:紧急指针有效
- ACK:确认序号有效
- PSH:接收方应该尽快将这个报文提交给上层
- RST:重新建立连接
- SYN:同步序号用来发起一个连接(用于建立连接三次握手)
- FIN:发送端完成发送任务(用于断开连接四次挥手)
- 窗口:流量控制,值为字节数,起始于确认号ack。
- 检验和:只是来校验首部是否出错
- 紧急指针:仅当URG为1时有效,为一个正的偏移量,和序号seq字段中的值相加,表示紧急数据最后一个字节的序号
- 选项:最常见的是最长报文大小(MSS,Maximum Segment Size)
TCP可靠数据传输机制:数据序号和确认号机制
上文已经介绍了TCP报文中的序号(seq)字段和确认号(ack)字段,下面通过一个例子,更直观地理解一下:
假设有两个主机A和B,窗口值为1000
下图忽略了时间间隔
那么在主机A上:
No1. 发送的数据将是序号3000~3999
,此时主机B已正确接收2999
以及之前的数据
No3. 发送的数据将是序号4000~4999
,此时主机B已正确接收3999
以及之前的数据
在主机B上:
No2. 发送的数据将是序号1000~1999
,此时主机A已正确接收999
以及之前的数据
特点
在数据序号和确认号机制中:
- 数据是无结构的有序字节流
- 确认机制是捎带(piggybacked)确认
- 确认号表明此序号之前的所有字节都已正确接收
- 失序保卫处理方式:back-to-N协议和选择重传协议
- 通信双方可有不同的初始序号,建立连接时通过协商告知对方
TCP连接的建立与终止
首先,TCP连接管理只涉及两个端系统,TCP服务器端和客户端
建立连接:三次握手
上图文字描述如下:
1. 客户机进程向服务器发送TCP SYN报文段(SYN=1
),指定初始序号seq=x
,无数据。(消耗序号)
2. 服务器收到SYN报文,用SYNACK报文回复(SYN=1,ACK=1
)。同时,服务器为该连接分配缓冲区和变量,指定服务器初始序号seq=y
,返回的确认号ack=x+1
。(消耗序号)
3. 客户收到SYNACK报文,用ACK报文回复(ACK=1
),可能包含数据。seq=x+1
,ack=y+1
。(若无数据,则这个报文段不消耗序号,所以在服务器开始发送数据的时候,序号seq=y+1
,确认号ack=x+1
)
终止连接:四次挥手
过程如下:
1. 客户A执行主动关闭,发送第一个TCP FIN报文(FIN=1
),序号seq=u
。(消耗序号)
2. 服务器B收到FIN报文,通知应用程序,执行被动关闭。返回一个ACK报文(ACK=1
),序号seq=v
,确认号ack=u+1
。这之后客户A不可再发送数据,而B仍然可以发送数据。(若无数据,则这个报文不消耗序号)
3. 服务器B进程释放,B不再发送数据,发送FINACK报文回复(FIN=1,ACK=1
),序号seq=v
(或者在关闭等待过程中有数据传输,则序号seq为一个新序号w),确认号ack=u+1
。(消耗序号)
4. 客户A收到FINACK报文,用ACK报文回复(ACK=1
),序号seq=u+1
,确认号ack=v+1
(或w+1)。再等待一段时间后(图中为2MSL,MSL(Maximum Segment Lifetime,报文段最大生存时间)),关闭连接。
ps:中间B还可以传送数据,A还可以接收B的数据,这样的状态称为TCP的半关闭
TCP的状态转换图
TCP的流量控制
- TCP流量控制仅涉及两个端系统,与底层网络网络无关
- TCP接收方有1个接收缓冲区,所以发送方的发送速率需要匹配接收方的处理速率,若发送得太快太多会导致接收方的缓冲区溢出
工作原理
- 两个端系统都维护一个变量:接收窗口,用来表明当前方接收缓存的使用情况。
用RWin表示接收窗口,接收缓冲区用RcvBuffer表示,LastByteRcvd和LastByteRead分别表示最后一个接收的字节的位置和应用程序最后一个提取的字节的位置,LastByteSent和LastByteAcked表示发送端最后发送的字节的位置和确认被接收的最后一个字节的位置,所以有,
LastByteRcvd - LastByteRead <= RcvBuffer
RWin = RcvBuffer - [LastByteRcvd - LastByteRead]
LastByteSent - LastByteAcked <= RWin
TCP拥塞控制
拥塞控制原理
网络拥塞条件:当对网络中的某种资源需求大于网络中的可用资源时,网络吞吐量会随输入负载的增大而急剧下降,网络进入拥塞状态。
拥塞控制思路:由于网络需求是动态的,应用对资源的需求是多方面的,需要引入适当的拥塞控制方法,从流量源头抑制流量的注入。
拥塞控制方法:1、端到端的拥塞控制(TCP采取的方法),可以从端系统根据报文的延时或丢失来判断拥塞;2、网络辅助的拥塞控制:由路由器向端系统提供反馈
TCP感知拥塞的方法
- 某TCP报文确认超时(报文丢失,网络拥塞,一点传输能力都没有了)
- 收到相同报文段的3个冗余ACK(说明报文段未按序到达,但是网络还是有一定的传输能力的)
TCP拥塞控制机制
-
慢启动(slow start):为发送方的TCP增加了另一个窗口–拥塞窗口(congestion window),记为cwnd,那么发送方的发送窗口的上限值
<= min{cwnd,RWin}
。- 连接开始时,
cwnd = 1 MSS
,逐步试探网络状态,指数增长至阈值ssthresh
- 连接开始时,
-
加性增:当慢启动指数增长至阈值ssthresh时,若未检测到丢包事件,每个单位时间(RTT)
cwnd += 1
-
乘性减:分为两种:TCPReno乘性减,TCPTahoe乘性减,对应两种不同的丢包事件。
- 新版TCPReno(又称快速恢复):若检测到3个冗余的ACK,说明网络还不是完全堵塞,先
ssthresh = cwnd / 2
,再cwnd = cwnd / 2
,再进入加性增状态 - TCPTahoe:若是报文超时,说明网络拥塞,先
ssthresh = cwnd / 2
,再将cwnd置为1 MSS,进入慢启动状态(图中废弃应该是不对的) - 新版TCP是包括了快速恢复方法,两种乘性减都有
- 新版TCPReno(又称快速恢复):若检测到3个冗余的ACK,说明网络还不是完全堵塞,先
- 快速重传:在RFC 2581中,一旦对某报文收到了3个冗余的ACK,可以在该报文段的定时器过期之前就重传丢失的报文段
TCP公平性
K条TCP连接共享带宽为R的链路瓶颈,每个会话应有R/K的平均链路速率
RTT与RTO
请参考TCP中RTT的测量和RTO的计算,写得很完备。
参考
《TCP/IP协议详解卷一:协议》LawrenceBerkeley 机械工业出版社
《计算机网络:原理与实践》陈鸣 高等教育出版社
西安邮电大学 谢晓燕老师