A unified, real-time communication protocol for chat messaging and file transfer over TCP
Features β’ Quick Start β’ Documentation β’ Contributing β’ License
- Overview
- Features
- Architecture
- Prerequisites
- Installation
- Quick Start
- Configuration
- Usage
- Protocol Specification
- API Documentation
- Development
- Deployment
- Security
- Performance
- Monitoring & Logging
- Troubleshooting
- FAQ
- Contributing
- Roadmap
- Changelog
- License
- Credits
UCP (Unified Communication Protocol) is a lightweight, high-performance application-layer protocol built in Go that enables real-time chat messaging and file transfer over a single TCP connection. Designed with simplicity and efficiency in mind, UCP provides a unified communication solution for local networks, development environments, and small-scale deployments.
- π Unified Protocol: Single TCP connection for both chat and file transfer
- π Network-Ready: Deploy on local networks with automatic IP detection
- π¦ Chunked Transfers: Efficient large file handling with 64KB chunks
- π Resume Support: Automatic recovery from connection interruptions
- π Activity Tracking: Comprehensive logging and monitoring
- ποΈ Modular Design: Clean architecture with separation of concerns
- β‘ High Performance: Built with Go for optimal concurrency and speed
- Local Network Communication: Team collaboration on private networks
- Development Environments: Quick file sharing and messaging during development
- Educational Projects: Learning network protocols and Go concurrency
- Small-Scale Deployments: Lightweight communication solution for small teams
- β Real-Time Chat Messaging: Instant message broadcasting to all connected clients
- β File Transfer: Send files of any size with automatic chunking
- β Multi-Client Support: Server handles unlimited concurrent connections
- β Connection Recovery: Resume interrupted file transfers automatically
- β Activity Logging: Comprehensive JSON-based activity tracking
- β Network Deployment: Automatic IP detection and network interface binding
- β Keep-Alive: PING/PONG mechanism for connection health monitoring
- β Graceful Shutdown: Clean server shutdown with signal handling
- π Thread-Safe Operations: All operations protected with mutex locks
- π Structured Logging: JSON-formatted logs for easy parsing
- π Cross-Platform: Works on Linux, macOS, and Windows
- π― Zero Dependencies: Pure Go implementation, no external dependencies
- π§ Configurable: Command-line arguments for port and host configuration
- π Client Tracking: Track connected clients with IP addresses and timestamps
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β UCP Server β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ β
β β Protocol β βTransport β β Handlers β β Tracking β β
β β Layer ββ β Layer ββ β Layer ββ β Layer β β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ β
β β β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β TCP Listener (0.0.0.0:8080) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β
β β β
ββββββββββ ββββββββββ ββββββββββ
βClient 1β βClient 2β βClient Nβ
ββββββββββ ββββββββββ ββββββββββ
- Message type definitions (JOIN, LEAVE, MSG, FILE, etc.)
- Message serialization/deserialization
- File chunking logic (64KB chunks)
- Protocol validation
- TCP connection management
- Message I/O operations
- Binary data handling for file transfers
- Connection state management
- Server-side message processing
- Client registration and management
- Message broadcasting
- File transfer coordination
- Chunk tracking and validation
- Resume logic for interrupted transfers
- File completion detection
- Activity logging
- JSON-formatted log entries
- Activity querying and filtering
Client β TCP Connection β Transport Layer β Protocol Parser
β
Server β TCP Connection β Transport Layer β Message Handler
β
Activity Tracker
βββββββββββ βββββββββββ βββββββββββ
β Client1 β β Server β β Client2 β
ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ
β β β
β 1. JOIN Alice β β
βββββββββββββββββββββββββββββββ>β β
β β β
β β 2. ACK β
β<βββββββββββββββββββββββββββββββ€ β
β β β
β β 3. Broadcast JOIN β
β βββββββββββββββββββββββββββββββ>β
β β β
β 4. MSG Hello β β
βββββββββββββββββββββββββββββββ>β β
β β β
β β 5. Broadcast MSG β
β βββββββββββββββββββββββββββββββ>β
β β β
β 6. FILE image.png (chunk 1/3) β β
βββββββββββββββββββββββββββββββ>β β
β β β
β β 7. Broadcast FILE β
β βββββββββββββββββββββββββββββββ>β
β β β
- Go 1.25.1 or higher - Download Go
- Git - For cloning the repository
- Network Access - For network deployment
- Docker - For containerized deployment
- Make - For using Makefile commands (optional)
- Wireshark - For network packet inspection (debugging)
- CPU: Any modern processor (x86_64, ARM64)
- RAM: Minimum 128MB, recommended 512MB+
- Storage: 50MB for binaries, additional space for logs
- Network: TCP/IP support, port 8080 (or custom) available
# Clone the repository
git clone https://github.com/yourusername/ucp.git
cd ucp
# Build the project
go build -o ucp-server ./server
go build -o ucp-client ./client
# Or use the build script
chmod +x build.sh
./build.sh# Example for Debian/Ubuntu (if package created)
sudo apt-get install ucp-server ucp-client# Clone the repository
git clone https://github.com/yourusername/ucp.git
cd ucp
# Build using Homebrew (if formula created)
brew install ucp
# Or build from source
go build -o ucp-server ./server
go build -o ucp-client ./client# Clone the repository
git clone https://github.com/yourusername/ucp.git
cd ucp
# Build the project
go build -o ucp-server.exe ./server
go build -o ucp-client.exe ./client
# Or use the build script
.\build.batchoco install ucp# Build server image
docker build -t ucp-server:latest -f Dockerfile.server .
# Build client image
docker build -t ucp-client:latest -f Dockerfile.client .# Start server
docker-compose up -d server
# Start client
docker-compose run --rm client 192.168.1.100 8080Dockerfile.server:
FROM golang:1.25-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o ucp-server ./server
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/ucp-server .
EXPOSE 8080
CMD ["./ucp-server"]Dockerfile.client:
FROM golang:1.25-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o ucp-client ./client
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/ucp-client .
CMD ["./ucp-client"]# Navigate to server directory
cd server
# Start server on default port (8080)
go run main.go
# Or use compiled binary
./ucp-server
# Custom port
go run main.go 9090Expected Output:
========================================
UCP Server started successfully!
Port: 8080
Network Access: Enabled (listening on all interfaces)
========================================
Server IP Addresses:
- localhost:8080
- 127.0.0.1:8080
- 192.168.1.100:8080
========================================
Clients can connect using any of the above IPs
Waiting for connections...
========================================
# Navigate to client directory
cd client
# Connect to localhost
go run main.go
# Connect to network server
go run main.go 192.168.1.100 8080
# Or use compiled binary
./ucp-client 192.168.1.100 8080> Enter your username: Alice
> Hello everyone!
> [Bob]: Hi Alice!
> /file document.pdf
> Sent file document.pdf successfully
Create a .env file in the project root:
# Server Configuration
UCP_SERVER_PORT=8080
UCP_SERVER_HOST=0.0.0.0
UCP_SERVER_MAX_CLIENTS=1000
UCP_SERVER_CHUNK_SIZE=65536
# Logging Configuration
UCP_LOG_LEVEL=info
UCP_LOG_FILE=logs/activity.log
UCP_LOG_MAX_SIZE=100MB
UCP_LOG_MAX_AGE=7
# Network Configuration
UCP_NETWORK_TIMEOUT=30s
UCP_KEEP_ALIVE_INTERVAL=60s
# Client Configuration
UCP_CLIENT_DOWNLOAD_DIR=downloads
UCP_CLIENT_TIMEOUT=30sExample .env file:
UCP_SERVER_PORT=8080
UCP_SERVER_HOST=0.0.0.0
UCP_LOG_LEVEL=info
UCP_LOG_FILE=logs/activity.log
UCP_CLIENT_DOWNLOAD_DIR=downloads| Parameter | Default | Description |
|---|---|---|
PORT |
8080 |
Server listening port |
HOST |
0.0.0.0 |
Network interface to bind to |
CHUNK_SIZE |
65536 |
File chunk size in bytes (64KB) |
MAX_CLIENTS |
1000 |
Maximum concurrent clients |
LOG_FILE |
logs/activity.log |
Activity log file path |
LOG_LEVEL |
info |
Logging level (debug, info, warn, error) |
| Parameter | Default | Description |
|---|---|---|
SERVER_HOST |
localhost |
Server hostname or IP |
SERVER_PORT |
8080 |
Server port |
DOWNLOAD_DIR |
downloads/ |
Directory for received files |
TIMEOUT |
30s |
Connection timeout |
# Start server on default port
ucp-server
# Start server on custom port
ucp-server 9090
# With environment variables
UCP_SERVER_PORT=9090 ucp-server# Connect to localhost:8080
ucp-client
# Connect to specific server
ucp-client 192.168.1.100 8080
# Connect with custom port
ucp-client localhost 9090Once connected, use these commands:
| Command | Description | Example |
|---|---|---|
/help |
Show help message | /help |
/file <path> |
Send a file | /file document.pdf |
/quit or /exit |
Quit the client | /quit |
/status |
Show client status | /status |
/ping |
Ping the server | /ping |
/files |
Show active file transfers | /files |
<message> |
Send chat message | Hello everyone! |
cd server
go run main.goNote the IP address displayed (e.g., 192.168.1.100).
Option A: Using Compiled Binary
- Copy
ucp-client.exe(orucp-clienton Linux/Mac) to Laptop 2 - Run:
./ucp-client 192.168.1.100 8080
Option B: Build on Laptop 2
- Copy entire project to Laptop 2
- Build client:
cd client go build -o ucp-client main.go - Run:
./ucp-client 192.168.1.100 8080
Windows:
# Allow inbound connections on port 8080
New-NetFirewallRule -DisplayName "UCP Server" -Direction Inbound -Protocol TCP -LocalPort 8080 -Action AllowLinux:
# Using ufw
sudo ufw allow 8080/tcp
# Using iptables
sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPTmacOS:
# Allow incoming connections
sudo pfctl -f /etc/pf.conf| Type | Format | Description |
|---|---|---|
JOIN |
JOIN <username> |
Client joins the server |
LEAVE |
LEAVE <username> |
Client leaves the server |
MSG |
MSG <username_len> <username> <msg_len> <message> |
Chat message |
FILE |
FILE <username_len> <username> <filename_len> <filename> <filesize> <chunk_num> <total_chunks>\n<4-byte length><data> |
File transfer chunk |
ACK |
ACK <message_id> |
Acknowledgment |
RESUME |
RESUME <username> <filename> <last_chunk_id> |
Resume file transfer |
PING |
PING |
Keep-alive ping |
PONG |
PONG |
Keep-alive response |
All text messages follow the format:
<COMMAND> [parameters]\n
File chunks are sent as:
FILE <username_length> <username> <filename_length> <filename> <filesize> <chunk_num> <total_chunks>\n
<4-byte length><binary data>
Where <4-byte length> is a big-endian 32-bit integer indicating the data size.
Files are automatically split into 64KB chunks for efficient transfer:
- Chunk Size: 65536 bytes (64KB)
- Last Chunk: May be smaller than 64KB
- Chunk Numbering: Starts at 0
- Metadata: Each chunk includes filename, size, and position
When a connection drops during file transfer:
- Client tracks received chunks
- On reconnect, client sends
RESUMEmessage - Server identifies missing chunks
- Server resends missing chunks
- Client completes file assembly
Request:
JOIN Alice
Response:
ACK 1234567890
Broadcast:
JOIN Alice
Request:
LEAVE Alice
Broadcast:
LEAVE Alice
Request:
MSG 5 Alice 13 Hello everyone!
Broadcast:
MSG 5 Alice 13 Hello everyone!
Parameters:
username_length: Length of username (5 for "Alice")username: Sender's usernamemessage_length: Length of message (13 for "Hello everyone!")message: Message content
Request:
FILE 5 Alice 8 image.png 192000 0 3
<65536 bytes of binary data>
Parameters:
username_length: Length of usernameusername: Sender's usernamefilename_length: Length of filenamefilename: File namefilesize: Total file size in byteschunk_num: Current chunk number (0-indexed)total_chunks: Total number of chunks<data>: Binary file data (preceded by 4-byte length)
Request:
RESUME Alice image.png 45
Response:
ACK 1234567891
Parameters:
username: Username requesting resumefilename: File to resumelast_chunk_id: Last successfully received chunk ID
| Code | Description | Solution |
|---|---|---|
CONNECTION_REFUSED |
Server not running or port blocked | Start server, check firewall |
USERNAME_TAKEN |
Username already in use | Choose different username |
INVALID_MESSAGE |
Malformed message format | Check message syntax |
FILE_NOT_FOUND |
File doesn't exist | Verify file path |
CHUNK_ERROR |
Chunk validation failed | Retry transfer |
ucp/
βββ client/ # Client executable
β βββ main.go # Client main entry point
βββ server/ # Server executable
β βββ main.go # Server main entry point
βββ protocol/ # Protocol definitions
β βββ protocol.go # Message types, parsing, serialization
βββ transport/ # Transport layer
β βββ connection.go # TCP connection handling
βββ handlers/ # Server handlers
β βββ handlers.go # Message handlers, client management
βββ recovery/ # Recovery system
β βββ tracker.go # Chunk tracking, resume logic
βββ tracking/ # Activity tracking
β βββ activity.go # Logging and activity tracking
βββ logs/ # Log files (generated)
β βββ activity.log # Activity log file
βββ build.bat # Windows build script
βββ build.sh # Linux/Mac build script
βββ go.mod # Go module file
βββ .gitignore # Git ignore rules
βββ README.md # This file
# Clone repository
git clone https://github.com/yourusername/ucp.git
cd ucp
# Download dependencies
go mod download
# Build server
go build -o ucp-server ./server
# Build client
go build -o ucp-client ./client
# Build both (Linux/Mac)
./build.sh
# Build both (Windows)
.\build.bat# Run all tests
go test ./...
# Run tests with coverage
go test -cover ./...
# Run tests with verbose output
go test -v ./...
# Run specific package tests
go test ./protocol
go test ./transport
go test ./handlers# Generate coverage report
go test -coverprofile=coverage.out ./...
# View coverage report
go tool cover -html=coverage.out
# Coverage threshold (example)
go test -cover -coverprofile=coverage.out ./...
go tool cover -func=coverage.out | grep total | awk '{if ($3+0 < 80) exit 1}'# Format code
go fmt ./...
# Run golint (if installed)
golint ./...
# Run go vet
go vet ./...
# Run staticcheck (if installed)
staticcheck ./...
# Run all checks
go fmt ./... && go vet ./... && go test ./...-
Fork the repository
-
Clone your fork:
git clone https://github.com/yourusername/ucp.git cd ucp -
Create a branch:
git checkout -b feature/your-feature-name
-
Make changes and test:
go test ./... go build ./... -
Commit changes:
git add . git commit -m "feat: add your feature"
-
Push and create PR:
git push origin feature/your-feature-name
Create /etc/systemd/system/ucp-server.service:
[Unit]
Description=UCP Server
After=network.target
[Service]
Type=simple
User=ucp
WorkingDirectory=/opt/ucp
ExecStart=/opt/ucp/ucp-server 8080
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl enable ucp-server
sudo systemctl start ucp-server
sudo systemctl status ucp-serverUse NSSM (Non-Sucking Service Manager):
# Install service
nssm install UCP-Server "C:\ucp\ucp-server.exe" "8080"
nssm start UCP-ServerCreate docker-compose.yml:
version: "3.8"
services:
ucp-server:
build:
context: .
dockerfile: Dockerfile.server
ports:
- "8080:8080"
volumes:
- ./logs:/app/logs
environment:
- UCP_SERVER_PORT=8080
- UCP_LOG_FILE=logs/activity.log
restart: unless-stopped
networks:
- ucp-network
networks:
ucp-network:
driver: bridgeDeploy:
docker-compose up -d
docker-compose logs -f ucp-server# Stop current version
systemctl stop ucp-server
# Restore previous binary
cp ucp-server.backup ucp-server
# Start previous version
systemctl start ucp-server# Rollback to previous image
docker-compose pull
docker-compose up -d --force-recreate- Encryption: Add TLS/SSL support
- Authentication: Implement user authentication
- Authorization: Add access control
- Rate Limiting: Prevent abuse
- Input Validation: Sanitize all inputs
- Network Isolation: Deploy on private networks only
- Firewall Rules: Restrict access to known IPs
- File Validation: Validate file types and sizes
- Logging: Monitor for suspicious activity
- Updates: Keep Go and dependencies updated
Store sensitive data in environment variables:
# Use .env file (not committed to git)
UCP_SECRET_KEY=your-secret-key-here
UCP_ADMIN_PASSWORD=secure-password# Rotate secrets
export UCP_SECRET_KEY=$(openssl rand -hex 32)
systemctl restart ucp-server- Concurrency: Go's goroutines handle thousands of concurrent connections
- Memory: Low memory footprint (~10-50MB per server instance)
- CPU: Minimal CPU usage for typical workloads
- Network: Optimized for local network speeds
- Deploy multiple server instances
- Use load balancer for distribution
- Each instance handles independent clients
- Increase server resources (CPU, RAM)
- Adjust
MAX_CLIENTSconfiguration - Optimize chunk size for network conditions
Currently, UCP doesn't implement caching. Future enhancements may include:
- File chunk caching
- Message history caching
- Client connection pooling
All server activity is automatically logged to logs/activity.log in JSON format.
{
"timestamp": "2025-11-18T20:56:48Z",
"type": "JOIN",
"username": "Alice",
"ip": "192.168.1.100:52341",
"data": {
"action": "joined"
}
}CONNECTION: Client connection/disconnectionJOIN: Client joined serverLEAVE: Client left serverMESSAGE: Chat message sentFILE: File transfer chunkERROR: Error occurred
# View recent activities
tail -f logs/activity.log
# Filter by username
grep '"username":"Alice"' logs/activity.log
# Filter by activity type
grep '"type":"FILE"' logs/activity.log
# Count activities
jq '.type' logs/activity.log | sort | uniq -c# Check if server is running
curl http://localhost:8080/health # If health endpoint added
# Check process
ps aux | grep ucp-server
# Check port
netstat -an | grep 8080# Ping server from client
/ping
# Check connection status
/statusSymptoms:
Failed to connect to server: dial tcp: connect: connection refused
Solutions:
- Verify server is running:
ps aux | grep ucp-server - Check port availability:
netstat -an | grep 8080 - Verify firewall rules
- Check server logs for errors
Symptoms:
Error: username Alice is already taken
Solutions:
- Choose a different username
- Wait for previous session to timeout
- Check if another client is using the name
Symptoms:
Failed to send file: file not found
Solutions:
- Verify file path is correct
- Check file permissions
- Ensure sufficient disk space
- Verify network stability
Symptoms:
dial tcp: i/o timeout
Solutions:
- Check network connectivity:
ping <server-ip> - Verify firewall allows connections
- Check server is accessible from client network
- Increase timeout value
Symptoms:
Missing chunk 5 for file document.pdf
Solutions:
- Retry file transfer
- Check network stability
- Verify server has sufficient resources
- Check server logs for errors
Modify log level in code:
log.SetFlags(log.LstdFlags | log.Lshortfile)# Use Wireshark to inspect packets
wireshark -i eth0 -f "tcp port 8080"
# Use tcpdump
tcpdump -i any -n port 8080# Run with debug output
UCP_LOG_LEVEL=debug ./ucp-serverQ: What is UCP?
A: UCP (Unified Communication Protocol) is a lightweight protocol for chat messaging and file transfer over TCP.
Q: Is UCP secure?
A: UCP is designed for trusted networks. For production use, add TLS encryption and authentication.
Q: What platforms are supported?
A: Linux, macOS, and Windows. Any platform that supports Go.
Q: Can I use UCP over the internet?
A: Technically yes, but it's designed for local networks. Use VPN or add security features for internet use.
Q: What is the maximum file size?
A: No hard limit. Files are chunked into 64KB pieces, so any size is supported.
Q: How many clients can connect?
A: Default is 1000, but can be configured. Limited by system resources.
Q: Does UCP support encryption?
A: Not currently. TLS support is planned for future releases.
Q: Can I customize the chunk size?
A: Yes, modify ChunkSize constant in protocol/protocol.go.
Q: How do I deploy on multiple servers?
A: Deploy multiple instances and use a load balancer, or run independent instances.
Q: Can I run server as a service?
A: Yes, use systemd (Linux), launchd (macOS), or NSSM (Windows).
Q: How do I backup logs?
A: Logs are in logs/activity.log. Use log rotation or backup scripts.
We welcome contributions! Please follow these guidelines:
main: Production-ready codedevelop: Development branchfeature/*: New featuresbugfix/*: Bug fixeshotfix/*: Critical fixes
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Ensure all tests pass
- Update documentation
- Submit pull request
Follow Conventional Commits:
feat: add TLS encryption support
fix: resolve connection timeout issue
docs: update README with deployment guide
test: add integration tests for file transfer
refactor: improve error handling
- Code follows Go style guidelines
- Tests added/updated
- Documentation updated
- No breaking changes (or documented)
- Performance considered
- Security implications reviewed
# 1. Create feature branch
git checkout -b feature/new-feature
# 2. Make changes
# ... edit files ...
# 3. Test changes
go test ./...
go build ./...
# 4. Commit
git add .
git commit -m "feat: add new feature"
# 5. Push
git push origin feature/new-feature
# 6. Create PR on GitHub- Add TLS/SSL encryption support
- Implement user authentication
- Add rate limiting
- Improve error messages
- Add health check endpoint
- Create web-based client interface
- Message persistence (database)
- File compression
- Multi-room/channel support
- Mobile client applications
- Admin dashboard
- Metrics and monitoring
- Distributed server architecture
- End-to-end encryption
- Voice/video support
- Plugin system
- API for third-party integrations
- Cloud deployment options
- Initial release
- Real-time chat messaging
- File transfer with chunking
- Connection recovery
- Activity tracking and logging
- Network deployment support
- Multi-client support
- Keep-alive mechanism
- Graceful shutdown
- N/A (initial release)
- N/A (initial release)
- Basic error handling
- Input validation
This project is licensed under the MIT License - see the LICENSE file for details.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
- Your Name - Initial work - YourGitHub
- Go community for excellent documentation and tools
- Contributors and testers
- Open source community
UCP is built with pure Go and has zero external dependencies (beyond the Go standard library).
Go Standard Library Packages Used:
net- Network operationsbufio- Buffered I/Oencoding/binary- Binary encodingfmt- Formattinglog- Loggingos- Operating system interfacesync- Synchronization primitivestime- Time operationsstrings- String manipulationpath/filepath- File path operations
- GitHub Issues: Open an issue
- Documentation: Check this README
- Examples: See usage examples above
When reporting bugs, please include:
- UCP version
- Operating system
- Steps to reproduce
- Expected behavior
- Actual behavior
- Logs (if applicable)
We welcome feature requests! Please:
- Check if feature already exists
- Describe the use case
- Explain the expected behavior
- Consider implementation complexity
If you find UCP useful, please consider giving it a star on GitHub!
Made with β€οΈ using Go