TCP中滑动窗口介绍

我们知道TCP协议中有一个确认应答机制,每发送一个数据段,就需要有一个ACK来响应,如果这样一收一发的话,会让数据传输的效率变得很低。滑动窗口就是用来解决这个问题的,也就是我们一次发送多条数据。例如现在不需要等待确认应答可以发送数据的最大值为4000个字节,我们将4000个字节分为四个数据段来进行发送。在发送前四个数据段的时候,我们不需要等待任何的ACK应答,可以直接发送。当收到第一个数据段的ACK之后,滑动窗口就会向后移动一个单元,再继续发送第五段数据,然后依次类推。

发送缓冲区

操作系统为了维护滑动窗口,会开辟一个发送缓冲区来记录当前有哪些数据没有被应答,只有确认应答过的数据,才会从缓冲区中删除掉。

也就是当发送端发送一个窗口大小的几段数据时,会将数据先保存在发送缓冲区中,如果收到了相应的ACK确认序号,就会将发送缓冲区中对应序列号的数据删除。如果没有收到ACK,就会根据相应情况重新发送数据段。通过发送缓冲区,可以有效地帮助发送端来解决数据的丢包问题。

接收缓冲区

保存数据和序号,用来告诉发送缓冲区应该删除哪些数据。

丢包问题

1.1 ACK丢失

ACK丢包也就是发送端将数据发送到服务端,服务端此时响应会一个ACK应答,但是这个ACK在中途丢失,并没有返回到发送端。不过在滑动窗口机制中,如果接收到一个ACK应答,根据返回的确认序号,可以知道接收端确认接收到数据的一个情况。

例如我们还是4000个字节,分为四个数据段发送。第一个数据段的ACK应答应该告诉发送端,我已经接收到了序列号1-1000的数据段,下一个发送数据应该是1001开始。假设这第一个ACK数据报在返回到发送端的中途丢失了,但是没关系,发送端可以根据第二个数据段响应的ACK来进行确认。就是说第二个数据段返回的ACK,其中会告诉发送端,我已经接收到了1-2000的数据,下一个发送数据应该是从2001开始发送。

1.2 数据包丢失

当发送端发送的某一个报文段丢失之后,就会连续收到该报文段对应起始序号的ACK,好比在提醒发送端,“我需要接下来的这个数据段“。如果发送端连续三次收到同样的应答,就会从发送缓冲区中将对应的数据段再次发送。这种机制被称为“高速重发控制”,也叫“快重传”。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TCP滑动窗口是一种流量控制机制,用于控制发送方和接收方之间的数据流量。它允许发送方在不等待确认的情况下发送多个数据包,而接收方可以根据自己的处理能力和可用缓冲区大小来控制数据的接收速度。 TCP滑动窗口的大小由接收方动态调整,以反映其可用的缓冲区大小。当接收方收到数据时,它会发送一个确认消息,其包含一个窗口大小值。这个值告诉发送方可以发送多少数据,而不必等待确认消息。 发送方维护一个发送窗口,它是一个连续的字节序列,表示可以发送但尚未得到确认的数据。发送方根据接收方发送的窗口大小值来调整发送窗口的大小。如果接收方的窗口大小值为0,发送方将停止发送数据,直到接收方发送一个非零的窗口大小值。 当发送方收到一个确认消息时,它会将发送窗口向前滑动,以删除已确认的数据,并将新的未确认数据添加到发送窗口。这个过程不断重复,直到所有数据都被确认。 下面是一个简单的TCP滑动窗口的例子: ```python # 假设接收方的窗口大小为10 window_size = 10 # 发送方的发送窗口 send_window = b"0123456789abcdefghijklmnopqrstuvwxyz" # 发送方已经发送但未确认的数据 unacked_data = b"" # 发送方已经发送并确认的数据 acked_data = b"" # 模拟发送数据 while send_window: # 如果接收方的窗口大小为0,停止发送数据 if window_size == 0: break # 计算可以发送的数据大小 data_size = min(len(send_window), window_size) # 从发送窗口取出数据 data = send_window[:data_size] # 将数据添加到未确认数据 unacked_data += data # 从发送窗口删除已经发送的数据 send_window = send_window[data_size:] # 更新窗口大小 window_size -= data_size # 模拟发送数据 # send(data) # 模拟接收确认消息 while unacked_data: # 模拟接收确认消息 # ack = receive_ack() ack = True if ack: # 从未确认数据删除已经确认的数据 acked_data += unacked_data[:window_size] unacked_data = unacked_data[window_size:] # 更新窗口大小 window_size += len(acked_data) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值