This project implements a custom application-layer protocol over TCP sockets to perform Vigenère cipher operations. The client reads data from stdin, sends it to the server for processing, and outputs the encrypted/decrypted result. The server handles multiple concurrent connections using process-based concurrency.
- Custom Protocol: Binary protocol with operation type, key length, data length, and payload
- Vigenère Cipher: Classical polyalphabetic substitution cipher implementation
- Large Data Support: Automatic chunking for data exceeding 10MB protocol limit
- Concurrent Server: Fork-based multi-process server supporting up to 50 simultaneous connections
- Binary Data Safe: Handles both text and binary data correctly
- Network Byte Order: Proper endianness handling for cross-platform compatibility
.
├── CSE351_PA1.pdf # Assignment specification
├── DockerSettingGuide.pdf # Docker environment setup guide
├── Dockerfile # Container configuration
├── Makefile # Build configuration
├── README.md # This file
├── client.c # Client implementation
├── common.h # Shared utilities and protocol definitions
├── server.c # Server implementation
├── run_tests.sh # Test automation script
├── test-sample/ # Sample input files
│ ├── 1K.txt # 1KB test input
│ ├── 3K.txt # 3KB test input
│ └── 5K.txt # 5KB test input
└── test-sample-result/ # Expected output files
├── 1K-dec.txt # 1KB decryption result
├── 1K-enc.txt # 1KB encryption result
├── 3K-dec.txt # 3KB decryption result
├── 3K-enc.txt # 3KB encryption result
├── 5K-dec.txt # 5KB decryption result
└── 5K-enc.txt # 5KB encryption result
The application uses a custom binary protocol with the following message format:
| Operation (16 bits) | Key Length (16 bits) | Data Length (32 bits) | Key + Data (variable) |
- Operation: 0 = encrypt, 1 = decrypt
- Key Length: Length of cipher key in bytes (network byte order)
- Data Length: Length of payload data in bytes (network byte order)
- Key + Data: Concatenated key string and data payload
Maximum message size is limited to 10MB (10,000,000 bytes).
- Docker (for consistent build environment)
- GCC compiler with C99 support
- Linux/Unix system
- Build the Docker image:
docker build -t network-env .- Create a Docker network:
docker network create --driver bridge my-network- Start server container:
docker run -it --name server --network my-network -v $(pwd):/workspace network-env- Start client container (in another terminal):
docker run -it --name client --network my-network -v $(pwd):/workspace network-envInside the Docker containers:
make clean
make allThis produces two executables: client and server.
Server:
./server -p <port>Client:
./client -h <server_ip> -p <port> -o <operation> -k <key> < input.txtParameters:
-h: Server IP address-p: Server port number-o: Operation (0 = encrypt, 1 = decrypt)-k: Vigenère cipher key
Terminal 1 (Server):
./server -p 8888Terminal 2 (Client):
# Encrypt
echo "Hello World" | ./client -h 172.18.0.2 -p 8888 -o 0 -k uailab
# Decrypt
echo "encrypted_text" | ./client -h 172.18.0.2 -p 8888 -o 1 -k uailabRun the automated test suite:
chmod +x run_tests.sh
./run_tests.shThe test script validates the implementation against provided sample inputs and expected outputs using the key "uailab".
- Converts all alphabetic characters to lowercase before processing
- Only processes alphabetic characters (a-z)
- Preserves numbers, spaces, and special characters unchanged
- Maintains key position continuity across message chunks
- Uses TCP sockets for reliable data transmission
- Implements proper send/receive loops to handle partial transfers
- All multi-byte integers transmitted in network byte order
- Graceful handling of connection errors and timeouts
- Server uses
fork()to create child processes for each client - Proper signal handling for child process cleanup
- Connection limiting to prevent resource exhaustion
- Graceful shutdown on SIGINT
- Process-based concurrency: Fork model chosen over threads for isolation and simplicity
- Streaming approach: Client processes data in chunks rather than loading everything into memory
- Protocol validation: Server validates all incoming messages and rejects malformed requests
- Binary safety: Implementation handles arbitrary binary data, not just text
- Standard C library (C99)
- POSIX system calls
- Linux networking APIs
No external libraries or frameworks are used beyond the standard C library and POSIX system calls.
This project was completed as Programming Assignment #1 for CSE351 Computer Networks at UNIST, Fall 2025. The implementation demonstrates understanding of:
- TCP socket programming
- Application-layer protocol design
- Process-based server architectures
- Network byte order handling
- Classical cryptography algorithms
This code is submitted as coursework for academic evaluation. Please respect academic integrity policies if you are a student taking this or similar courses.