产生TCP ACK的情况及其 建议
快速重传
就是在快速定时器超时之前已经收到了某个段的冗余ACK, 那么就需要在某个段还没有到时的情况下,将这个段快速重新传出去 ,而不是等待它超时了再进行重传。
- 超时周期往往太长:
- 在重传丢失报文段之前的 延时太长
- 通过重复的ACK来检测 报文段丢失
- 发送方通常连续发送大量 报文段
- 如果报文段丢失,通常会 引起多个重复的ACK
如果发送方收到同一数据 的3个冗余ACK,重传最 小序号的段:
==快速重传:在定时器过时 之前重发报文段==
它假设跟在被确认的数据 后面的数据丢失了
• 第一个ACK是正常的;
• 收到第二个该段的ACK,表 示接收方收到一个该段后的 乱序段;
• 收到第3,4个该段的ack,表 示接收方收到该段之后的2个 ,3个乱序段,可能性非常大 段丢失了
快速重传算法:
event: ACK received, with ACK field value of y if (y > SendBase) { SendBase = y if (there are currently not-yet-acknowledged segments) start timer } else { //已确认报文段的一个重复确认 increment count of dup ACKs received for y if (count of dup ACKs received for y = 3) { //快速重传 resend segment with sequence number y }
流量控制
目的就是防止发送方发送的太快, 而使得接收方得缓冲区溢出。
- 接收方在其向发送方的TCP段 头部的rwnd字段“通告”其空 闲buffer大小
- RcvBuffer大小通过socket选项 设置 (典型默认大小为4096 字 节)
- 很多操作系统自动调整 RcvBuffer
- 发送方限制未确认(“inflight”)字节的个数≤接收 方发送过来的 rwnd 值
- 保证接收方不会被淹没
TCP流量控制
相当于木桶效应, 即使发送方能够发送4096bit得数据。 但是接收方只能接收1080bit的数据, 那么发送方也只能有效发出1080bit的数据。
连接管理
连接的本质:
- ==双方都知道要和对方通信==
- ==双方要为通信连接准备好必要的资源(初始序号等)==
- ==控制变量需要做置位(序号、初始化receiveBuffer(接收窗口)大小等都需要告诉对方)==*
在正式交换数据之前,发送方和接收方握手建立通信关系:
- 同意建立连接(每一方都知道对方愿意建立连接)
- 同意连接参数
为连接做 准备
两次握手建立连接的不可行性
- 变化的延迟(连接请求的段 没有丢,但可能超时)
- 由于丢失造成的重传 (e.g. req_conn(x))
- 报文乱序
- 相互看不到对方
2次握手失败的场景:
Client发送了建立连接的请求, 然后Server收到连接请求, 并且进行了确认, 然后发送给了Client 。Client接收到了Server的连接确认, 表示Client知道Server是活跃的, 但是之后Client并没有继续发送确认信息。 因为握手已经结束, 所以Server并不知道你Client是否活跃,所以这就是所谓的半连接。
TCP 三次握手
基于2次握手的不可行性, 我们通过三次握手来实现解决。
基本方案是 : 变化的初始序号+双方确认对方的序号(3次握手)
1.Client建立起连接 。然后将自己的初始序号, x发送TCP SYN报文。
SYN = 1 就是连接请求, Seq = x 就是告诉对方,我将要从x这个字节开始传输。(x就是初始序号)
2.Server接收到连接请求 ,发出连接确认。
SYN = 1 表示连接请求, Seq = y 就是告诉Client我要从y这个字节开始传输(y就是server的初始序号)
ACK =1 表示我确认接收到了连接请求,ACKNum 表示我确认接收到了x的请求 ,希望你下次从x+1开始传输
3.Client接收到了第二次握手的信号,发出第三次握手
接收到SYN = 1 表示Server是活跃的, 发送SYNACK 的ACK表示 该报文可能包含C-S的数据
接收到了Server的初始序号Seq = y, 本次我就要确认Server给的初始序号。
并且发送ACK = 1表示Client确认了这次的请求。ACKNum = y+1 表示我确认接收到了y的请求 ,希望你下次从y+1开始传输
4.Server接收到Client的确认请求。
ACK(y)表示Client是活跃的。
通常第三次握手跟第一次的数据传递是放在一块的。
3次握手解决:半连接和接收老数据问题
因为三次握手首先需要将初始序号(x)告诉对方, 然后收到对方的确认之后, 再进行后续的传输,如果说client本次传输的序号不是(x+1) 那么Server就会refuse。 就不会出现老数据传输
TCP 三次握手 : FSM
TCP: 关闭连接
- 客户端,服务器分别关闭它自己这一侧的连接【通过发送FIN bit = 1的TCP段 】
- 一旦接收到FIN,用ACK回应 【 接到FIN段,ACK可以和它自己发出的FIN段一起发 送
- 可以处理同时的FIN交换