# NXST Wire Protocol ## Overview NXST uses two sockets per transfer session: | Socket | Purpose | |--------|---------| | UDP multicast | Receiver advertisement (discovery) | | TCP | File data stream | Both sides must be on the same local network segment. The sender (Transfer mode) initiates; the receiver (Receive mode) listens. --- ## Discovery — UDP Multicast | Parameter | Value | |-----------|-------| | Group | `239.0.0.1` | | Port | `8081` | | Direction | sender → receiver | **Flow:** 1. Receiver joins multicast group and binds `0.0.0.0:8081`. 2. Sender sends `"DISCOVER_SERVER"` (15 bytes, no null terminator) to `239.0.0.1:8081`. 3. Receiver replies `"SERVER_HERE"` (11 bytes) to the sender's source address. 4. Sender extracts the receiver's IP from the reply source and closes the UDP socket. Sender polls in 100 ms slices for up to 3 seconds. Cancel is checked each slice. --- ## File Transfer — TCP | Parameter | Value | |-----------|-------| | Port | `8080` | | Direction | sender connects → receiver listens | | Buffer size | 65 536 bytes (`proto::BUF_SIZE`) | **Connection:** 1. Receiver listens on `0.0.0.0:8080` (started concurrently with multicast listener). 2. Sender connects after receiving `"SERVER_HERE"`. **Wire layout — one file:** ``` ┌─────────────────────────────────┐ │ filename_len │ uint32_t LE │ 4 bytes ├─────────────────────────────────┤ │ filename │ filename_len │ bytes, no null terminator │ │ bytes │ ├─────────────────────────────────┤ │ file_size │ uint64_t LE │ 8 bytes ├─────────────────────────────────┤ │ file_data │ file_size │ bytes │ │ bytes │ └─────────────────────────────────┘ ``` Files are sent sequentially. The stream ends with a sentinel frame: ``` filename_len == 0 (proto::EOF_SENTINEL) ``` No `filename` or `file_size` field follows the sentinel. **Constraints:** - `filename_len > proto::MAX_FILENAME` (4 096) is treated as a protocol error; the receiver aborts. - Filenames are full paths as produced by `io::backup` (e.g. `/switch/NXST/