Skip to content
W
Book a call

Project 04 / 04 · Networking · C++ · University

Peer-to-peer file sharing over UDP

A C++ tool that shares files between computers on a local network over UDP, adding its own packets, sequence numbers and checksums.

  • C++
  • UDP sockets
  • Checksums
  • Linux
Peer-to-peer file sharing over UDP screenshot

(01) Why I built it

Why I built it

UDP is fast but makes no promises: packets can be lost, duplicated or arrive out of order. The Computer Networks project at FAST asked us to move files across a deliberately unreliable channel and build the reliability ourselves, close to how TCP does it, with a client, a server and test code designed to break other teams' work.

(02) How it works

How it works

  1. 01

    Cutting the file into packets

    The sender reads the file and splits it into 500-byte packets. Each packet carries its data, a sequence number and a checksum.

  2. 02

    Checking every packet

    Each packet gets a 16-bit ones'-complement checksum, the same kind used in IP and UDP headers. The receiver recomputes it on arrival, so a damaged packet is caught before it goes into the file.

  3. 03

    Putting it back together

    The receiver uses the sequence numbers to rebuild the file in order and replies to the sender over the same socket.

  4. 04

    Designed for a hostile network

    The brief went further: sliding windows, acknowledgements and timeouts, retransmission, CRC-16 error detection, many clients at once with POSIX threads, and configuration files that drop or corrupt packets on purpose to prove the design holds up.

Stack · C++ · POSIX sockets · UDP · Linux

(03) From the source

From the source

The packet and the checksum, from the original source

struct packet_struct {
  int  checksum;
  char data[500];
  int  sequence_no;
};

uint16_t checksum(void *buffer, size_t len) {
  const uint16_t *buff = (uint16_t *) buffer;
  uint32_t sum = 0;
  while (len > 1) {
    sum += *buff++;
    if (sum & 0x80000000) sum = (sum & 0xFFFF) + (sum >> 16);
    len -= 2;
  }
  if (len & 1) sum += *((uint8_t *) buff);
  while (sum >> 16) sum = (sum & 0xFFFF) + (sum >> 16);
  return (uint16_t) ~sum;
}

What it taught me

What it taught me

Writing reliability by hand is the fastest way to understand why TCP looks the way it does. Every header field I take for granted now is there because someone once lost a packet.

Next project

HQ, an AI virtual office