Untitled
unknown
plain_text
9 months ago
3.8 kB
13
Indexable
import socket
import yaml
import time
import struct
with open("configs/server.yml", "r") as config_file:
config = yaml.safe_load(config_file)
SERVER_PORT = config["server"]["port"]
BUFFER_SIZE = config["server"]["buffer_size"]
FILENAME = config["filename"]
class Packet:
def __init__(self, data):
# First 4 bytes are sequence number
self.seq_num = struct.unpack("!I", data[:4])[0]
self.data = data[4:] # Rest is payload
def send_ack(sock, seq_num, addr):
ack = struct.pack("!I", seq_num)
sock.sendto(ack, addr)
print(f"[ACK] Sent for packet {seq_num}")
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.bind(("", SERVER_PORT))
print(f"[Listening] on port {SERVER_PORT}...")
# Receive file size first
data, addr = s.recvfrom(BUFFER_SIZE)
packet = Packet(data)
file_size = int(packet.data.decode())
send_ack(s, packet.seq_num, addr)
print(f"[Expected] File size: {file_size} bytes")
expected_seq = 1
total_received = 0
received_packets = set()
out_of_order_packets = 0
duplicate_packets = 0
missing_packets = 0
retransmission_requests = 0
start_time = time.time()
with open(FILENAME, "wb") as f:
while True:
try:
data, addr = s.recvfrom(BUFFER_SIZE + 4) # +4 for sequence number
packet = Packet(data)
# Check if this is the end marker
if packet.seq_num == 0xFFFFFFFF:
print(f"[Received] End marker - Message: {packet.data.decode()}")
send_ack(s, packet.seq_num, addr)
print("[Complete] End of transmission received")
break
print(f"[Received] Packet {packet.seq_num}: {len(packet.data)} bytes")
if packet.seq_num == expected_seq:
if packet.seq_num in received_packets:
duplicate_packets += 1
print(f"[Duplicate] Packet {packet.seq_num}")
else:
# Write data and send ACK
f.write(packet.data)
received_packets.add(packet.seq_num)
total_received += len(packet.data)
send_ack(s, packet.seq_num, addr)
expected_seq += 1
else:
# Received out-of-order packet
out_of_order_packets += 1
print(f"[Out-of-order] Expected {expected_seq}, got {packet.seq_num}")
send_ack(s, expected_seq - 1, addr)
retransmission_requests += 1
except struct.error as e:
print(f"[Error] Failed to unpack packet: {e}")
continue
end_time = time.time()
duration = end_time - start_time
speed = total_received / (1024 * 1024 * duration) if duration > 0 else float("inf")
# Calculate missing packets
expected_packets = expected_seq - 1 # Total expected packets
missing_packets = expected_packets - len(received_packets)
print("\n[Complete] File transfer finished")
print(f"[Stats] Total received: {total_received} bytes")
print(f"[Stats] Time: {duration:.4f}s, Speed: {speed:.4f} MB/s")
print(
f"[Stats] Expected packets: {expected_packets}, "
f"Received unique packets: {len(received_packets)}\n"
f"[Stats] Out-of-order packets: {out_of_order_packets}, "
f"Duplicate packets: {duplicate_packets}\n"
f"[Stats] Missing packets: {missing_packets}, "
f"Retransmission requests: {retransmission_requests}"
)
print("[Closing] server...")
Editor is loading...
Leave a Comment