使用python实现基于socket的滑动窗口模拟
时间: 2024-01-01 21:07:01 浏览: 114
这里提供一个简单的基于socket的滑动窗口模拟实现,代码如下:
```python
import socket
import time
# 定义发送方和接收方的IP和端口号
sender_ip = '127.0.0.1'
sender_port = 8888
receiver_ip = '127.0.0.1'
receiver_port = 9999
# 定义数据包大小和窗口大小
packet_size = 1024
window_size = 4
# 创建UDP socket
sender_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
receiver_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定接收方的IP和端口号
receiver_socket.bind((receiver_ip, receiver_port))
# 定义发送方和接收方的初始序号和确认序号
sender_seq = 0
sender_ack = 0
receiver_seq = 0
receiver_ack = 0
# 定义发送方和接收方的窗口
sender_window = []
receiver_window = []
# 发送数据
def send_data(data):
global sender_seq, sender_ack, sender_window
# 将数据分割成数据包
packets = [data[i:i+packet_size] for i in range(0, len(data), packet_size)]
for packet in packets:
# 将数据包打包成字节串
packet_bytes = str(sender_seq).encode() + b':' + packet
# 发送数据包
sender_socket.sendto(packet_bytes, (receiver_ip, receiver_port))
# 将数据包加入发送方窗口
sender_window.append(packet_bytes)
# 更新发送方序号
sender_seq += len(packet)
# 如果发送方窗口大小超过了窗口大小,等待接收方的确认,直到发送方窗口大小小于等于窗口大小
while len(sender_window) > window_size:
time.sleep(0.1)
receive_ack()
# 接收数据
def receive_data():
global receiver_seq, receiver_ack, receiver_window
# 接收数据包
packet_bytes, _ = receiver_socket.recvfrom(packet_size + 32)
# 解析数据包
seq_bytes, packet = packet_bytes.split(b':', 1)
seq = int(seq_bytes.decode())
# 如果序号不是期望的序号,直接丢弃数据包
if seq != receiver_seq:
return
# 将数据包加入接收方窗口
receiver_window.append(packet)
# 更新接收方序号
receiver_seq += len(packet)
# 更新接收方确认序号
receiver_ack = receiver_seq
# 发送确认消息
send_ack()
# 发送确认消息
def send_ack():
global receiver_ack
# 发送确认消息,确认序号为接收方序号
receiver_socket.sendto(str(receiver_ack).encode(), (sender_ip, sender_port))
# 接收确认消息
def receive_ack():
global sender_ack, sender_window
# 接收确认消息
ack_bytes, _ = sender_socket.recvfrom(packet_size)
# 解析确认消息
ack = int(ack_bytes.decode())
# 更新发送方确认序号
sender_ack = ack
# 从发送方窗口中删除已经确认的数据包
while sender_window and int(sender_window[0].split(b':', 1)[0].decode()) < sender_ack:
sender_window.pop(0)
if __name__ == '__main__':
# 发送数据
send_data('hello world')
# 接收数据
while True:
receive_data()
if receiver_ack == sender_seq:
break
# 关闭socket
sender_socket.close()
receiver_socket.close()
```
该代码实现了一个简单的滑动窗口模拟,通过UDP socket发送和接收数据包,并实现了滑动窗口的功能。在发送数据时,将数据分割成数据包,并将数据包打包成字节串发送。在接收数据时,解析数据包,并将数据包加入接收方窗口,更新接收方序号和确认序号,然后发送确认消息。在发送确认消息时,确认序号为接收方序号。在接收确认消息时,更新发送方确认序号,并从发送方窗口中删除已经确认的数据包。通过循环接收数据,并等待接收方确认,直到所有数据都被接收方确认。最后关闭socket。
阅读全文