计算机网络中GBN协议算法具体代码
时间: 2023-12-14 11:53:33 浏览: 147
以下是GBN协议的Python代码实现:
发送端代码:
```python
from socket import *
import time
serverName = 'localhost'
serverPort = 12000
# 创建客户端套接字
clientSocket = socket(AF_INET, SOCK_DGRAM)
# 设置超时时间
clientSocket.settimeout(1)
# 发送窗口大小
N = 4
# 初始化变量
base = 0
nextseqnum = 0
pkt = []
# 读取文件
f = open('file.txt', 'r')
data = f.read()
# 分割数据
for i in range(0, len(data), 500):
pkt.append(data[i:i+500])
while True:
# 发送窗口未满
if nextseqnum < base + N:
# 发送数据包
message = pkt[nextseqnum]
clientSocket.sendto(message.encode(), (serverName, serverPort))
# 输出发送信息
print('Sent packet', nextseqnum)
# 第一个数据包发送时开始计时
if nextseqnum == base:
start_time = time.time()
# 增加序列号
nextseqnum += 1
# 发送完最后一个数据包,退出循环
if nextseqnum == len(pkt):
break
try:
# 接收ACK
ack, serverAddress = clientSocket.recvfrom(2048)
# 解析ACK序号
acknum = int(ack.decode())
# 输出接收信息
print('Received ACK', acknum)
# 确认ACK是否在窗口内
if acknum >= base and acknum < nextseqnum:
# 滑动窗口
base = acknum + 1
# 判断是否收到最后一个ACK
if base == len(pkt):
break
except timeout:
# 超时重传
print('Timeout, sequence number =', base)
nextseqnum = base
# 重新发送窗口内的数据包
for i in range(base, base+N):
message = pkt[i]
clientSocket.sendto(message.encode(), (serverName, serverPort))
print('Resent packet', i)
# 重置计时器
start_time = time.time()
# 输出传输时间
end_time = time.time()
print('Transmission time:', end_time - start_time, 'seconds')
# 关闭套接字
clientSocket.close()
```
接收端代码:
```python
from socket import *
serverPort = 12000
# 创建服务器套接字
serverSocket = socket(AF_INET, SOCK_DGRAM)
# 绑定服务器端口
serverSocket.bind(('', serverPort))
# 接收窗口大小
N = 4
# 初始化变量
expectedseqnum = 0
while True:
# 接收数据包
message, clientAddress = serverSocket.recvfrom(2048)
# 解析数据包序号
seqnum = int(message.decode())
# 输出接收信息
print('Received packet', seqnum)
# 判断是否是期望的数据包
if seqnum == expectedseqnum:
# 发送ACK
ack = str(seqnum)
serverSocket.sendto(ack.encode(), clientAddress)
# 输出发送信息
print('Sent ACK', seqnum)
# 增加期望序号
expectedseqnum += 1
# 判断是否是重复的数据包
elif seqnum < expectedseqnum:
# 发送ACK
ack = str(seqnum)
serverSocket.sendto(ack.encode(), clientAddress)
# 输出发送信息
print('Sent ACK', seqnum)
# 判断是否是超出窗口范围的数据包
else:
# 不发送ACK,等待发送端重传
print('Discarded packet', seqnum)
```
阅读全文