📜  门| GATE 2017 MOCK II |问题 12(1)

📅  最后修改于: 2023-12-03 15:42:10.257000             🧑  作者: Mango

问题 12

本问题关于计算机网络中的TCP协议。给定一个网络拓扑,其中有一个源主机(Host A)和一个目的主机(Host B),它们之间通过多个路由器(Router 1~4)连接。Host A 想要向 Host B 发送大量数据,需要分成多个分组进行传输。假设 Host A 创建了一个长度为 $m$ 字节的数据报,每个分组的最大长度为 $n$ 字节(不考虑 TCP 头部),Host A 希望每个分组发送成功后接收确认,并尽可能快地发送下一个分组。如果 TCP 使用的滑动窗口大小为 $k$ 字节,那么 Host A 需要设置多少分组才能保持最大的发送窗口不断开?

解题思路

本题需要理解 TCP 发送分组的滑动窗口机制。TCP 的滑动窗口机制通过接收端向发送端发送确认消息,告诉发送端自己已经接收到哪些数据,从而实现流量控制和拥塞控制。

滑动窗口的大小是发送端和接收端协商得出的,它表示发送端可以向接收端发送多少个字节的数据。发送端维护了一个发送窗口,它表示可以发送但还未得到确认的字节数。发送窗口的大小就是发送端和接收端协商得出的滑动窗口大小减去已经得到确认的字节数。

如果发送窗口的大小为 $0$,意味着发送端不能继续发送数据,需要等待接收端发送确认消息之后才能继续发送数据。当发送窗口不为 $0$ 时,发送端就可以继续发送数据,同时滑动窗口的大小也会随着已发送但未确认的数据的确认消息的到来而不断向右移动。发送窗口的大小最大不能超过 $k$ 字节。

在本题中,为了保持最大的发送窗口不断开,需要控制发送窗口的大小不超过 $k$ 字节。因此,需要计算最少需要发送多少个分组才能保持最大的发送窗口不断开。具体的计算方法如下:

  1. 计算每个分组传输时需要占用的 TCP 头部长度,假设 TCP 头部长度为 $h$ 字节。

  2. 每次发送一个分组,会收到一个确认消息。因此,每个分组可以传输 $n-h$ 字节的数据。因为滑动窗口的大小不能超过 $k$ 字节,因此需要在接收到确认消息之前保留 $k$ 字节的空间。

  3. 如果当前发送窗口的大小小于 $k$ 字节,则需要发送下一个分组来填满窗口。否则,需要等待接收到确认消息,将已经得到确认的字节数从发送窗口中减去,然后再发送新的数据。

  4. 计算需要发送的分组数。因为每个分组传输了 $n-h$ 字节的数据,因此需要传输 $m / (n-h)$ 个分组。但是,因为每个分组之间需要保留 $k$ 字节的空间,因此实际需要发送的分组数为 $Ceil(m/(n-k-h))$。其中,$Ceil(x)$ 表示对 $x$ 向上取整。

代码实现
# 问题 12

本问题关于计算机网络中的TCP协议。给定一个网络拓扑,其中有一个源主机(Host A)和一个目的主机(Host B),它们之间通过多个路由器(Router 1~4)连接。Host A 想要向 Host B 发送大量数据,需要分成多个分组进行传输。假设 Host A 创建了一个长度为 $m$ 字节的数据报,每个分组的最大长度为 $n$ 字节(不考虑 TCP 头部),Host A 希望每个分组发送成功后接收确认,并尽可能快地发送下一个分组。如果 TCP 使用的滑动窗口大小为 $k$ 字节,那么 Host A 需要设置多少分组才能保持最大的发送窗口不断开?

## 解题思路

本题需要理解 TCP 发送分组的滑动窗口机制。TCP 的滑动窗口机制通过接收端向发送端发送确认消息,告诉发送端自己已经接收到哪些数据,从而实现流量控制和拥塞控制。

滑动窗口的大小是发送端和接收端协商得出的,它表示发送端可以向接收端发送多少个字节的数据。发送端维护了一个发送窗口,它表示可以发送但还未得到确认的字节数。发送窗口的大小就是发送端和接收端协商得出的滑动窗口大小减去已经得到确认的字节数。

如果发送窗口的大小为 $0$,意味着发送端不能继续发送数据,需要等待接收端发送确认消息之后才能继续发送数据。当发送窗口不为 $0$ 时,发送端就可以继续发送数据,同时滑动窗口的大小也会随着已发送但未确认的数据的确认消息的到来而不断向右移动。发送窗口的大小最大不能超过 $k$ 字节。

在本题中,为了保持最大的发送窗口不断开,需要控制发送窗口的大小不超过 $k$ 字节。因此,需要计算最少需要发送多少个分组才能保持最大的发送窗口不断开。具体的计算方法如下:

1. 计算每个分组传输时需要占用的 TCP 头部长度,假设 TCP 头部长度为 $h$ 字节。

2. 每次发送一个分组,会收到一个确认消息。因此,每个分组可以传输 $n-h$ 字节的数据。因为滑动窗口的大小不能超过 $k$ 字节,因此需要在接收到确认消息之前保留 $k$ 字节的空间。

3. 如果当前发送窗口的大小小于 $k$ 字节,则需要发送下一个分组来填满窗口。否则,需要等待接收到确认消息,将已经得到确认的字节数从发送窗口中减去,然后再发送新的数据。

4. 计算需要发送的分组数。因为每个分组传输了 $n-h$ 字节的数据,因此需要传输 $m / (n-h)$ 个分组。但是,因为每个分组之间需要保留 $k$ 字节的空间,因此实际需要发送的分组数为 $Ceil(m/(n-k-h))$。其中,$Ceil(x)$ 表示对 $x$ 向上取整。

## 代码实现

```python
import math

m = int(input("请输入数据报长度 m:"))
n = int(input("请输入分组最大长度 n:"))
k = int(input("请输入滑动窗口大小 k:"))
h = int(input("请输入 TCP 头部长度 h:"))

# 计算需要发送的分组数
num = math.ceil(m / (n - k - h))

print("需要发送的分组数为:", num)
程序使用
  1. 在命令行中运行 Python 程序。

  2. 输入数据报长度、分组最大长度、滑动窗口大小和 TCP 头部长度,按 Enter。

  3. 程序会输出需要发送的分组数。

例如:

输入数据报长度 m:1000
请输入分组最大长度 n:150
请输入滑动窗口大小 k:100
请输入 TCP 头部长度 h:20
需要发送的分组数为: 8

注意:这里假设输入的值都是符合要求的,没有进行异常处理。实际使用中需要注意输入的值是否合法。