Skip to content

tahaekim/COMP416-Project2

Repository files navigation

Project 2 — Sensor Data Streaming over TCP and SSL

Course: COMP 416 — Computer Networks, Koç University
Semester: Fall 2024
Student ID: 79234


Overview

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:

  1. Part 1 — Implement a multi-threaded TCP server and client for sensor data streaming, and analyze the traffic with Wireshark.
  2. Part 2 — Add SSL/TLS support on top of the existing TCP implementation, using Java's SSLSocket / SSLServerSocket with a self-signed certificate and truststore.
  3. 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.

What it does

The basic idea is pretty straightforward:

  1. You start the server — it listens on two ports simultaneously, one for TCP and one for SSL.
  2. You start the client, pick a protocol and a sensor type, set how fast you want readings and for how long.
  3. 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.


Project Structure

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

How to Run

Prerequisites

  • 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

Generating the keystore (if needed)

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 -noprompt

Starting the Server

Compile and run from the project root:

cd Server/src
javac *.java
cd ../..
java -cp Server/src ServerMain

You 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
-------------------------------------

Starting the Client

In a separate terminal:

cd Client/src
javac *.java
cd ../..
java -cp Client/src ClientMain

You'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.


Supported Sensor Types

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>


Protocol Details

TCP (Port 5555)

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.

SSL/TLS (Port 4444)

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.


Benchmarking

The benchmark mode (option 2 in the client menu) does the following:

  1. Runs 10 TCP streaming sessions back-to-back (TEMP sensor, 20ms rate, 10s each)
  2. Runs 10 SSL streaming sessions with the same config
  3. For each session, records the timestamp of every received message relative to the connection start
  4. Computes and prints:
    • Average time to first message (includes connection setup + server processing)
    • Average inter-message delay
  5. Exports all raw data to benchmark_results.csv

The CSV has columns: Run, Protocol, MessageIndex, ArrivalTime, FirstMessageTime, LastMessageTime

Analyzing with MATLAB

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.


Architecture Notes

A few things about how the code is organized that might not be obvious:

  • Multi-threaded server: Each client connection gets its own thread (TCPServerThread or SSLServerThread). The main server threads just sit in accept loops.

  • BaseServerThread abstraction: 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 TCPClient and SSLClient have two methods — connectAndStream() for normal interactive use (prints everything to console) and connectAndStreamWithTiming() 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.


Wireshark Captures

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.


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

Ports

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.


Known Limitations

  • Only supports localhost connections out of the box. To connect to a remote server, you'd need to change SERVER_ADDRESS in ClientMain.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.

Tools Used

  • 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 .iml files are IntelliJ project files)

About

No description or website provided.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors