A multi-user chat system built over TCP that evolved from a JSON-based prototype into an efficient binary protocol (ChatProto v1.0) with TLS/SSL encryption. Developed as a semester project for EE586.
ChatProto is a binary application-layer protocol for real-time chat. The project demonstrates the design, implementation, and iterative improvement of a networked application across four versions:
| Version | Description | Protocol | Security |
|---|---|---|---|
| v1 | Baseline functional chat | JSON over TCP | None |
| v2 | Enhanced error handling | JSON over TCP | None |
| v3 | Custom binary protocol | ChatProto v1.0 (binary) | None |
| v4 | TLS encryption | ChatProto v1.0 (binary) | TLS 1.2+ |
The binary protocol achieves 41% bandwidth savings over JSON, and even with TLS encryption (v4), it remains 26% more efficient than JSON+TLS.
- Python 3.6+
- No external dependencies (uses only standard library:
socket,threading,struct,ssl,json)
Each version has its own server script. The latest (v4) is recommended:
python3 Server/chat_server_v4.py [port] [certfile] [keyfile]| Argument | Default | Description |
|---|---|---|
port |
5555 |
TCP port to listen on |
certfile |
server.crt |
Path to SSL certificate (v4 only) |
keyfile |
server.key |
Path to SSL private key (v4 only) |
Examples:
# Start v4 server with defaults (port 5555, included self-signed cert)
python3 Server/chat_server_v4.py
# Start on a custom port
python3 Server/chat_server_v4.py 8888
# Start with custom certificates
python3 Server/chat_server_v4.py 5555 /path/to/my.crt /path/to/my.key
# Start earlier versions (no TLS)
python3 Server/chat_server_v3.py # Binary protocol, no TLS
python3 Server/chat_server_v2.py # JSON protocol
python3 Server/chat_server_v1.py # JSON baselineThe server binds to 0.0.0.0 (all interfaces) and prints a log line when ready:
[INFO] Server started on 0.0.0.0:5555
[INFO] Waiting for connections...
python3 Clients/chat_client_v4.py <username> [host] [port]| Argument | Default | Description |
|---|---|---|
username |
(required) | Display name (max 20 characters) |
host |
127.0.0.1 |
Server IP address or hostname |
port |
5555 |
Server port |
Examples:
# Connect to a local server
python3 Clients/chat_client_v4.py alice
# Connect to a server on the local network
python3 Clients/chat_client_v4.py bob 192.168.1.100
# Connect to a remote server on a custom port
python3 Clients/chat_client_v4.py charlie chat.example.com 8888Once connected, type messages directly to send them to the current room. Prefix with / for commands:
| Command | Aliases | Description |
|---|---|---|
/join <room> |
/j |
Switch to a different room (creates it if new) |
/msg <user> <message> |
/m, /pm, /dm, /whisper |
Send a private message |
/users |
/who, /list |
List users in the current room |
/rooms |
/r |
List all available rooms |
/help |
/h, /? |
Show help |
/quit |
/exit, /q |
Disconnect and exit |
Example session:
> Hello everyone! # Send message to current room
> /join tech-talk # Switch to tech-talk room
> /msg bob Hey, are you around? # Private message to bob
> /users # See who's in this room
> /rooms # See all rooms
> /quit # Disconnect
The included server.crt and server.key are self-signed certificates for testing. To regenerate:
cd Server/
openssl req -x509 -newkey rsa:2048 -nodes \
-keyout server.key -out server.crt -days 365 \
-subj "/CN=localhost/O=ChatProto/C=US"Open three terminals:
# Terminal 1 - Start the server
python3 Server/chat_server_v4.py
# Terminal 2 - Connect as alice
python3 Clients/chat_client_v4.py alice
# Terminal 3 - Connect as bob
python3 Clients/chat_client_v4.py bobMessages typed in one client appear in all other clients in the same room. All users start in the general room.
EE586Project/
├── Server/
│ ├── chat_server_v1.py # v1 - JSON baseline
│ ├── chat_server_v2.py # v2 - Enhanced error handling
│ ├── chat_server_v2_tls.py # v2 - JSON with TLS (for comparison)
│ ├── chat_server_v3.py # v3 - Binary protocol
│ ├── chat_server_v4.py # v4 - Binary protocol + TLS
│ ├── server.crt # Self-signed SSL certificate
│ └── server.key # Private key
├── Clients/
│ ├── chat_client_v1.py # v1 - JSON baseline
│ ├── chat_client_v2.py # v2 - Enhanced error handling
│ ├── chat_client_v2_tls.py # v2 - JSON with TLS (for comparison)
│ ├── chat_client_v3.py # v3 - Binary protocol
│ └── chat_client_v4.py # v4 - Binary protocol + TLS
├── pcaps/
│ ├── v2_traffic.pcap # JSON plaintext capture
│ ├── v2_tls_traffic.pcap # JSON + TLS capture
│ ├── v3_traffic.pcap # Binary plaintext capture
│ └── v4_traffic.pcap # Binary + TLS capture
└── documentation/
├── CHAT_PROTO_SPECIFICATION.pdf/md # Protocol specification
├── READMEv1.pdf/md # v1 documentation
├── READMEv2.pdf/md # v2 documentation
├── READMEv3.pdf/md # v3 documentation
├── READMEv4.pdf/md # v4 documentation
└── Binary_Protocol_Presentation.pptx
ChatProto v1.0 uses a 9-byte fixed header followed by length-prefixed UTF-8 fields:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Protocol Number (0x4350) | Version | Type | Flags |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Body Length (bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Protocol ID:
0x4350("CP" for ChatProto) - 12 message types: LOGIN, LOGIN_ACK, LOGIN_REJECT, ROOM_MSG, PRIVATE_MSG, PRIVATE_MSG_DELIVERY, JOIN_ROOM, LIST_USERS, LIST_ROOMS, SYSTEM_MSG, ERROR_MSG, ROOM_MSG_ACK
- Struct format:
!HBBBL(network byte order)
See CHAT_PROTO_SPECIFICATION.md for the full specification.
JSON-based client/server chat with rooms, private messaging, and threaded connection handling. Documentation
Specific error types (DNS, connection refused, timeout), input validation, structured logging, and actionable troubleshooting guidance. Documentation
Replaced JSON with ChatProto v1.0 binary protocol. 50% reduction on LOGIN messages, 46% on ROOM_MSG. Same user experience, much smaller wire footprint. Documentation
Added TLS 1.2+ encryption via Python's ssl module. Self-signed certificates for testing, same binary protocol underneath. Breaks even with JSON plaintext after ~5 minutes of session time. Documentation
From actual network captures (163-183 seconds, 5 users):
| Protocol | TCP Payload | Bandwidth | vs JSON |
|---|---|---|---|
| v2 (JSON) | 656,550 B | 32.07 Kbps | baseline |
| v2+TLS (JSON+TLS) | 804,598 B | 39.28 Kbps | +22.5% |
| v3 (Binary) | 386,444 B | 19.02 Kbps | -41.1% |
| v4 (Binary+TLS) | 594,154 B | 25.97 Kbps | -9.5% |
- Default port: 5555
- Server binds:
0.0.0.0(all interfaces) - Client defaults:
127.0.0.1
# Server with custom port
python3 Server/chat_server_v4.py 8888
# Client with remote host
python3 Clients/chat_client_v4.py alice 192.168.1.100 5555The pcaps/ directory contains Wireshark captures for each version. Open them to compare:
- v2/v3: Plaintext traffic -- message content visible in packet data
- v2_tls/v4: Encrypted traffic -- only TLS handshake and encrypted blobs visible