Untitled
unknown
plain_text
2 months ago
4.4 kB
6
Indexable
import socket import yaml import time import struct import logging from datetime import datetime import os # Setup logging log_dir = "logs/udp_server" os.makedirs(log_dir, exist_ok=True) log_filename = f"{log_dir}/udp_server_reliable_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log" logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler(log_filename), logging.StreamHandler() ] ) logger = logging.getLogger(__name__) 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) logger.info(f"[ACK] Sent for packet {seq_num}") with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: s.bind(("", SERVER_PORT)) logger.info(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) logger.info(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: logger.info(f"[Received] End marker - Message: {packet.data.decode()}") send_ack(s, packet.seq_num, addr) logger.info("[Complete] End of transmission received") break logger.debug(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 logger.warning(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 logger.warning(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: logger.error(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) # Log final statistics logger.info("\n=== Transfer Summary ===") logger.info(f"[Stats] Total received: {total_received} bytes") logger.info(f"[Stats] Time: {duration:.4f}s, Speed: {speed:.4f} MB/s") logger.info( f"[Stats] Expected packets: {expected_packets}, " f"Received unique packets: {len(received_packets)}" ) logger.info( f"[Stats] Out-of-order packets: {out_of_order_packets}, " f"Duplicate packets: {duplicate_packets}" ) logger.info( f"[Stats] Missing packets: {missing_packets}, " f"Retransmission requests: {retransmission_requests}" ) logger.info("[Closing] server...")
Editor is loading...
Leave a Comment