Untitled
unknown
plain_text
2 months ago
3.8 kB
6
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