Course: COMP 416 — Computer Networks, Koç University
Semester: Fall 2024
Student ID: 79234
This is the second project for COMP 416. The goal was to build a client-server system in Java that streams simulated sensor data over the network using two different protocols — plain TCP and SSL/TLS — and then compare their performance.
The project had three main parts:
- Part 1 — Implement a multi-threaded TCP server and client for sensor data streaming, and analyze the traffic with Wireshark.
- Part 2 — Add SSL/TLS support on top of the existing TCP implementation, using Java's
SSLSocket/SSLServerSocketwith a self-signed certificate and truststore. - Part 3 — Run benchmarks to compare TCP vs SSL in terms of connection setup overhead, time-to-first-message, and inter-message delay. Capture and analyze packets with Wireshark, and visualize the results using MATLAB.
The basic idea is pretty straightforward:
- You start the server — it listens on two ports simultaneously, one for TCP and one for SSL.
- You start the client, pick a protocol and a sensor type, set how fast you want readings and for how long.
- The server streams simulated sensor data back to you at the requested rate until the duration runs out.
That's really it. The more interesting part is the analysis — comparing how TCP and SSL differ at the packet level (handshake overhead, encryption cost, etc.) and measuring the performance gap with the built-in benchmark mode.
Project2/
├── Server/
│ └── src/
│ ├── ServerMain.java # Entry point, spins up both TCP and SSL servers
│ ├── TCPServer.java # Accepts plain TCP connections
│ ├── SSLServer.java # Accepts SSL/TLS connections (uses keystore)
│ ├── BaseServerThread.java # Abstract class — handles the streaming logic
│ ├── TCPServerThread.java # TCP-specific server thread
│ ├── SSLServerThread.java # SSL-specific server thread
│ └── SensorSimulator.java # Generates random sensor readings
│
├── Client/
│ ├── truststore # Trust store for SSL certificate verification
│ └── src/
│ ├── ClientMain.java # Entry point, interactive menu
│ ├── TCPClient.java # Connects to the TCP server
│ ├── SSLClient.java # Connects to the SSL server (uses truststore)
│ └── BenchmarkRunner.java # Runs repeated TCP/SSL sessions and collects timing data
│
├── Matlab/
│ ├── part3_q3.m # MATLAB script for analyzing benchmark results
│ └── benchmark_results.csv # Sample benchmark output
│
├── Wireshark/
│ ├── part1.pcapng # Packet capture for Part 1
│ ├── part3-q1.1.pcapng # Packet capture for Part 3 Q1
│ ├── part3-q1.2.pcapng # Packet capture for Part 3 Q1
│ └── udp_sample.pcapng # UDP sample capture
│
├── alice.txt # Text file (used in Part 1 for TCP file transfer)
├── benchmark_results.csv # Benchmark output (root-level copy)
└── report_79234-1.pdf # Project report with analysis and screenshots
- Java 8 or later (I used JDK 17 but anything recent should work)
- The keystore file for the server (
Server/keystore.jks) needs to exist — if it doesn't, you'll need to generate one (see below) - The truststore file for the client (
Client/truststore) is already included
If Server/keystore.jks is missing, you can create a self-signed certificate with:
keytool -genkeypair -alias server -keyalg RSA -keysize 2048 \
-storetype PKCS12 -keystore Server/keystore.jks \
-storepass storepass -keypass storepass \
-dname "CN=localhost"Then export and import it into the client's truststore:
keytool -exportcert -alias server -keystore Server/keystore.jks \
-storepass storepass -file server.cer
keytool -importcert -alias server -file server.cer \
-keystore Client/truststore -storepass storepass -nopromptCompile and run from the project root:
cd Server/src
javac *.java
cd ../..
java -cp Server/src ServerMainYou should see:
-------------------------------------
Sensor Streaming Server Application
-------------------------------------
Starting TCP Server on port 5555
TCP Server is up and running on port 5555
Starting SSL Server on port 4444
SSL Server is up and running on port 4444
-------------------------------------
Both servers are running!
TCP Server: port 5555
SSL Server: port 4444
-------------------------------------
In a separate terminal:
cd Client/src
javac *.java
cd ../..
java -cp Client/src ClientMainYou'll get an interactive menu:
----- Sensor Streaming Client -----
Select mode:
1. Normal streaming
2. Benchmark mode
Enter choice (1 or 2):
Normal streaming — pick TCP or SSL, choose a sensor, set a rate (in ms) and duration (in ms), and watch the data come in.
Benchmark mode — automatically runs 10 TCP sessions and 10 SSL sessions with the same parameters (TEMP sensor, 20ms rate, 10s duration), records all message arrival timestamps, prints a summary, and exports everything to benchmark_results.csv.
| Sensor | Code | Range |
|---|---|---|
| Temperature | TEMP |
20.0 – 30.0 °C |
| Humidity | HUM |
40.0 – 80.0 % |
| Pressure | PRES |
980.0 – 1050.0 hPa |
| Light | LIGHT |
0.0 – 1000.0 lux |
| Acceleration | ACC |
0.0 – 5.0 m/s² |
Each reading from the server looks like:
TEMP 1700000000000 24.7
That's: <sensor_type> <timestamp_ms> <value>
Standard unencrypted TCP socket connection. The client sends a single line subscription in the format <SENSOR_TYPE> <RATE_MS> <DURATION_MS>, and the server starts pushing readings at the requested rate. When the duration is up, the server closes the connection.
Same exact application-level protocol, but wrapped in TLS. The server loads its private key from a PKCS12 keystore (Server/keystore.jks), and the client verifies the server's certificate using its truststore (Client/truststore). After the handshake completes, everything works identically to TCP from the application's perspective.
The SSL setup uses SSLContext with TLS protocol and SunX509 key manager on the server side. The client sets javax.net.ssl.trustStore system properties before creating the socket factory.
The benchmark mode (option 2 in the client menu) does the following:
- Runs 10 TCP streaming sessions back-to-back (TEMP sensor, 20ms rate, 10s each)
- Runs 10 SSL streaming sessions with the same config
- For each session, records the timestamp of every received message relative to the connection start
- Computes and prints:
- Average time to first message (includes connection setup + server processing)
- Average inter-message delay
- Exports all raw data to
benchmark_results.csv
The CSV has columns: Run, Protocol, MessageIndex, ArrivalTime, FirstMessageTime, LastMessageTime
There's a MATLAB script in Matlab/part3_q3.m that reads the CSV and produces bar charts comparing TCP vs SSL performance. It calculates:
- Average time to first message for each protocol
- Average delay between consecutive messages
Just make sure the CSV file is in the same directory (or adjust the path) and run the script.
A few things about how the code is organized that might not be obvious:
-
Multi-threaded server: Each client connection gets its own thread (
TCPServerThreadorSSLServerThread). The main server threads just sit in accept loops. -
BaseServerThreadabstraction: Both TCP and SSL server threads extend this. It handles the subscription parsing, sensor streaming loop, and connection cleanup. The subclasses just provide the socket-specific I/O streams and close methods. This avoids duplicating the streaming logic. -
Timing in the streaming loop: The server doesn't just
Thread.sleep(rate)— it calculates the next absolute time a reading should be sent and sleeps only the remaining difference. This prevents drift from accumulating over long sessions. -
Benchmark vs normal mode in the client: Both
TCPClientandSSLClienthave two methods —connectAndStream()for normal interactive use (prints everything to console) andconnectAndStreamWithTiming()for benchmark mode (silently collects timing data into a result object). -
Graceful shutdown: The server registers a JVM shutdown hook that closes both server sockets when you hit Ctrl+C.
The Wireshark/ folder has packet captures that correspond to different parts of the assignment:
- part1.pcapng — Captured during Part 1 to observe the TCP 3-way handshake and plain-text data transfer between the client and server.
- part3-q1.1.pcapng and part3-q1.2.pcapng — Captured during Part 3 to compare TCP and SSL/TLS traffic side by side. You can clearly see the extra round trips in the TLS handshake (ClientHello, ServerHello, certificate exchange, etc.) versus the simple SYN-ACK of TCP.
- udp_sample.pcapng — A separate UDP capture used for reference/comparison in the report.
These were analyzed in Wireshark and screenshots were included in the written report.
The file report_79234-1.pdf contains the full project report with:
- Wireshark screenshots and packet analysis for both TCP and SSL connections
- Explanation of the TCP 3-way handshake vs. the TLS handshake process
- Benchmark results and performance comparison (tables and charts)
- Discussion of why SSL is slower than TCP and where the overhead comes from
- MATLAB-generated bar charts for time-to-first-message and inter-message delay
| Service | Port |
|---|---|
| TCP Server | 5555 |
| SSL Server | 4444 |
Both are hardcoded in ServerMain.java and ClientMain.java. If you need to change them, update both files.
- Only supports
localhostconnections out of the box. To connect to a remote server, you'd need to changeSERVER_ADDRESSinClientMain.java(and make sure the SSL certificate's CN matches the server hostname). - The keystore password is hardcoded as
"storepass"— not something you'd do in a real application, but it keeps things simple for a class project. - There's no error recovery or reconnection logic. If the connection drops mid-stream, the client just prints an error and exits.
- The benchmark parameters (sensor type, rate, duration, number of runs) are constants in
BenchmarkRunner.java. You'd need to recompile to change them.
- Java (JDK 17) — for the client and server implementation
- Wireshark — for capturing and analyzing network packets
- MATLAB — for processing benchmark data and generating comparison charts
- keytool (part of JDK) — for generating the SSL keystore and truststore
- IntelliJ IDEA — as the IDE (the
.imlfiles are IntelliJ project files)