TCP 可靠传输的实现
确认序号是期望对方发送数据的序号
发送窗口的描述
发送窗口的位置由窗口前沿和后沿的位置共同确定。窗口里面的序号表示允许发送的序号。
后沿 | 前沿 | |
---|---|---|
位置特征 | 前沿的后面部分表示已发送且已收到了确认这些数据不需要再保留。 | 前沿的前面部分表示不允许发送的,因为接收方都没有为这部分数据保留临时存放的缓存空间。 |
变化情况 |
|
|
要描述一个发送窗口的状态需要三个指针:P1,P2 和 P3
窗口段 | 数据状态 |
---|---|
P3 – P1 | 发送窗口 |
P2 – P1 | 已发送但尚未收到确认的字节数 |
P3 – P2 | 当前尚未发送的字节数(可用窗口、有效窗口) |
- A 收到 B 发来的确认报文段,根据其中窗口( 20 字节)、确认号(31→ 表明 B 期望收到的下一个序号是 31,而序号 30 为止的数 据已经收到了) 这两个数据构造出自己的发送窗口。
- A 可以连续把窗口内的数据都发送出去。发送的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用。
- B 的接收窗口大小是 20。在接收窗口外的数据已经发送过确认,并且已经交付主机了,可以不再保留。窗口内的序号(31 ~ 50)是允许接收的。
- 若 A 已发送到 41,B 收到了序号为 32 和 33 的数据,31 的数据没有收到(也许丢失了,也许滞留在网络中的某处)。B 只能对按序收到的数据中的最高序号给出确认,因此确认报文段中的确认号仍然是 31。
- B 收到了序号为 31 的数据,并把序号为 31 ~ 33 的数据交付主机,然后 B 删除这些数据。接着把接收窗口向前移动 3 个序号,同时给 A 发送确认,其中窗口值仍为 20,但确认号是 34。
- A 收到 B 的确认后,就可以把发送窗口向前滑动 3 个序号,但指针 P2 不动,现在 A 的可用窗口增大了,可发送的序号范围是 42 ~ 53。
(2013年真题·39)主机甲与主机乙之间己建立一个 TCP 连接,双方持续有数据传输,且数据无差错与丢失。若甲收到 1 个来自乙的 TCP 段,该段的序号为 1913 、确认序号为 2046 、有效载荷为100 字节,则甲立即发送给乙的 TCP 段的序号和确认序号分别是
A. 2046 、2012
B. 2046 、 2013
C. 2047 、 2012
D. 2047 、 2013
答案 B
TCP协议的拥塞控制
算法名称 | 描述 |
---|---|
慢开始 (Slow Start) | 每经过一个传输轮次,发送方的拥塞窗口 cwnd 加倍(初始为不超过 2 至 4 个发送方的最大报文段 SMSS (Sender Maximum Segment Size)的数值)。 |
拥塞避免 (Congestion Avoidance) | 拥塞窗口大小达到慢开始门限 ssthresh 时,将拥塞窗口控制为按线性规律增长,每经过一个 RTT 把 cwnd 加 1。 网络出现超时,则调整门限值 ssthresh = cwnd / 2,同时设置 cwnd = 1,进入慢开始阶段 |
快重传 (Fast Retransmit) | 当发送方连续收到多个重复的确认时,表明某个报文段丢失,发送方会立即重传该报文段,而不必等待超时。 |
快恢复 (Fast Recovery) | 在快重传后,发送方调整门限值 ssthresh = cwnd / 2 = 8,同时设置拥塞窗口 cwnd = ssthresh 或 ssthresh + 3 × MSS, 并开始执行拥塞避免算法 |
真题
【2009题39】一个TCP连接总是以1KB的最大段长发送TCP段,发送方有足够多的数据要发送。当拥塞窗口为16KB时发生了超时,如果接下来的4个RTT(往返时间)时间内的TCP段的传输都是成功的,那么当第4个RTT时间内发送的所有TCP段都得到肯定应答时,拥塞窗口大小是()。
A. 7KB B. 8KB C. 9KB D. 16KB
TCP 的运输连接管理
TCP 连接的建立
TCP 建立连接的过程叫做握手,握手需要在客户和服务器之间交换三个 TCP 报文段。
三报文握手建立连接过程
最初两端的 TCP 进程都处于 CLOSED(关闭)状态。A 主动打开连接,而 B 被动打开连接:
阶段 | 标志事件 |
---|---|
B → LISTEN (收听) | B 的 TCP 服务器进程先创建传输控制块 TCB,准备接受客户进程的连接请求。 |
A → SYN-SENT (同步已发送) | A 的 TCP 客户进程创建传输控制模块 TCB。在打算建立 TCP 连接时, 向 B 发出连接请求报文段,首部中:
|
B → SYN-RCVD (同步收到) | B 发送确认。确认报文段中:
|
A → ESTABLISHED (已建立连接) | A 向 B 给出确认。确认报文段:
|
B → ESTABLISHED (已建立连接) | B 收到 A 的确认 |
四报文握手
B 发送给 A 的报文段,也可拆成两个报文段。可以先发送一个确认报文段(ACK = 1, ack = x + 1),然后再发 送一个同步报文段(SYN = 1, seq = y)。这样的过程就变成了四报文握手,但效果是一 样的。
客户端发送最后一次确认的目的
防止已失效的连接请求报文段突然又传送到了服务端,导致服务端等待客户端发送数据,造成资源浪费。
- A 发出连接请求而未收到确认,再重传连接请求,收到后确认建立了连接。数据传输完毕后释放了连接。
- 请求报文段在某些网络结点长时间滞留了,以致延误到连接释放以后的某个时间才到达 B。
- B 收到失效的连接请求报文段后误认为是新的连接请求,发出确认报文段。并一直等待 A 发来数据,导致 B 的资源浪费。
采用三报文握手的办法,A 不会向 B 的确认发出确认。B 由于收不到确认,就知道 A 并没有要求建立连接。