SocketSpeak is a CLI messaging app written in C for local-area-network peer chat. It supports peer-to-peer one-on-one conversations, group chat, ASCII-art stickers, and a synchronous Hangman minigame. The project is designed to stay lightweight and dependency-free beyond a C compiler, make, and pthreads.
- Peer-to-peer auto-discovery over UDP broadcast for one-on-one chat.
- Group chat through a central group server.
- Persistent storage for usernames, chat history, and stickers under
~/lmp/<username>/. - ASCII-art sticker creation, preview, and sending.
- Group-only Hangman gameplay.
- Tested on Linux (Debian) and macOS.
- GCC or Clang
make- A POSIX-like environment with pthread support
The project is compiled in ANSI C mode with pedantic checks enabled through the Makefile.
makeThis builds the main binaries in bin/:
bin/main- One-on-One Chatbin/gserver- Group Chatbin/gclient- Group Chat
It also builds the test binaries under bin/.
Start either peer with the main binary:
./bin/main [-u <username>]The -u flag sets the program username used for persistent storage. If omitted, the program uses default as program username.
Runtime flow:
- Each peer broadcasts its local IPv4 address over UDP to
255.255.255.255:8082. - The program waits up to 5 seconds for an incoming TCP connection on port
8081. - If a connection arrives, that instance acts as the client side inside the application.
- If the accept times out, the instance switches to UDP discovery mode and waits for another peer to broadcast.
- When a broadcast is received, it connects back over TCP to port
8081and acts as the server side inside the application.
Start the group server:
./bin/gserverConnect a group client:
./bin/gclientThe group client broadcasts a UDP discovery signal, waits for a server response, and then connects over TCP.
Once connected, plain text is sent as a message. Commands are prefixed with /.
| Command | Description | Mode |
|---|---|---|
| plain text | Send a plain-text message | P2P, Group |
/msg <text> |
Explicitly send a message | P2P, Group |
/nick <name> |
Set your nickname and persist it | P2P, Group |
/sticker <action> ... |
Create, send, list, or preview ASCII-art stickers | P2P |
/gi |
Display group info, including member nicknames and UIDs | Group |
/load |
Request and display group message history | Group |
/hangman <action> |
Start, join, or exit the Hangman game | Group |
/meow <text> |
Demo command | P2P, Group |
Stickers can be created, listed, previewed, and sent with the /sticker command in P2P chat only.
/sticker create <sticker_name>
/sticker send <sticker_name>
/sticker list
/sticker preview <sticker_name>createopens a multiline terminal editor for drawing the sticker.- Press
ESCto finish editing and save the sticker. - Stickers are stored in
~/lmp/<username>/saved_stickers.txt. sendthe sticker to other peers in the chat.previewshows the sticker locally without sending it.
Hangman is available in group chat only.
/hangman start
/hangman join
/hangman exitstartinitializes a new game.joinjoins an active game.exitleaves the game and returns to normal messaging.
SocketSpeak uses a custom binary framing protocol called LMP. Each frame is an 8-byte header followed by a variable-length payload.
| Field | Size | Description |
|---|---|---|
| Magic | 2 bytes | Fixed value 0x4C4D (LM) |
| Type | 1 byte | Command or message type |
| Reserved | 1 byte | Reserved for future use |
| Payload length | 4 bytes | Big-endian uint32 payload size |
| Payload | N bytes | Message body |
The payload length supports messages up to 4 GB.
Client-side user data is stored under ~/lmp/<username>/, including:
uid.txtfor the local user UIDnick.txtfor the current nicknamesaved_stickers.txtfor sticker definitions (P2P sticker feature)peers/<peer_uid>/nick.txtfor a peer's saved nickname (P2P)peers/<peer_uid>/history.txtfor one-on-one chat history with that peer (P2P)
This makes user-specific state persistent across sessions.
Group chat history is stored on the group server under ~/lmp/server/<group_uid>/:
history.txtfor chat history