This document provides a detailed explanation of the 5 network programming concepts implemented in the Online Quiz System.
TCP (Transmission Control Protocol) is a connection-oriented protocol that provides reliable, ordered, and error-checked delivery of data between applications.
// Create server socket and bind to port
ServerSocket serverSocket = new ServerSocket(tcpPort);
// Accept incoming client connections
Socket clientSocket = serverSocket.accept();Key Features:
- Reliable Connection: Ensures data arrives in order without loss
- Three-Way Handshake: Establishes connection before data transfer
- Bidirectional Communication: Both client and server can send/receive
// Connect to server
Socket socket = new Socket(SERVER_HOST, SERVER_PORT);
// Get input/output streams
BufferedReader input = new BufferedReader(
new InputStreamReader(socket.getInputStream())
);
PrintWriter output = new PrintWriter(
socket.getOutputStream(), true
);- Quiz Questions: Server sends questions to clients
- Answer Submission: Clients send answers to server
- Score Updates: Server sends score updates to clients
✅ Guaranteed delivery
✅ Data arrives in order
✅ Error detection and correction
✅ Flow control
❌ Higher overhead than UDP
❌ Slower than UDP
❌ Requires connection establishment
Multithreading allows a program to execute multiple threads concurrently, enabling efficient handling of multiple tasks simultaneously.
// Create thread pool for handling multiple clients
ExecutorService executorService = Executors.newFixedThreadPool(maxClients);
// Execute each client handler in separate thread
ClientHandler clientHandler = new ClientHandler(clientSocket, quizService, this);
executorService.execute(clientHandler);public class ClientHandler implements Runnable {
@Override
public void run() {
// Each client runs in its own thread
handleClient();
}
}- Multiple Clients: Each client connection runs in a separate thread
- Concurrent Processing: Server handles all clients simultaneously
- Non-Blocking: Server can accept new connections while handling existing ones
✅ Concurrent Handling: Multiple clients can play simultaneously
✅ Better Performance: CPU utilization is optimized
✅ Scalability: Can handle many clients (up to thread pool limit)
✅ Responsiveness: Server remains responsive while handling clients
- Shared resources must be synchronized
- Prevents race conditions
- Ensures data consistency
Synchronization is a mechanism that ensures thread-safe access to shared resources, preventing race conditions and data corruption.
// Synchronized method - only one thread can execute at a time
public synchronized boolean addPlayer(String clientId, String playerName) {
if (players.containsKey(clientId)) {
return false;
}
players.put(clientId, new Player(playerName, clientId));
return true;
}
public synchronized void removePlayer(String clientId) {
players.remove(clientId);
}// Synchronized block for critical section
synchronized (scoreLock) {
Player player = players.get(clientId);
if (player != null) {
player.incrementScore(10);
}
}// ConcurrentHashMap - thread-safe map
private final Map<String, Player> players = new ConcurrentHashMap<>();
// CopyOnWriteArrayList - thread-safe list
private final List<ClientHandler> clients = new CopyOnWriteArrayList<>();- Player Management: Adding/removing players safely
- Score Updates: Updating scores without race conditions
- Quiz State: Managing quiz progression across threads
Thread 1: Read score = 10
Thread 2: Read score = 10
Thread 1: Write score = 20 (10 + 10)
Thread 2: Write score = 20 (10 + 10)
Result: Score = 20 (Should be 30!)
Thread 1: Lock → Read score = 10 → Write score = 20 → Unlock
Thread 2: Wait → Lock → Read score = 20 → Write score = 30 → Unlock
Result: Score = 30 (Correct!)
✅ Data Integrity: Prevents data corruption
✅ Consistency: Ensures correct results
✅ Thread Safety: Multiple threads can safely access shared data
UDP (User Datagram Protocol) is a connectionless protocol that sends data without establishing a connection, offering fast but unreliable delivery.
Broadcasting sends data to all devices on a network simultaneously, without needing individual addresses.
// Create UDP socket
DatagramSocket socket = new DatagramSocket();
socket.setBroadcast(true);
// Prepare data
byte[] buffer = results.getBytes();
InetAddress broadcastAddr = InetAddress.getByName("255.255.255.255");
// Create and send datagram packet
DatagramPacket packet = new DatagramPacket(
buffer,
buffer.length,
broadcastAddr,
UDP_PORT
);
socket.send(packet);// Create UDP socket to receive broadcasts
DatagramSocket socket = new DatagramSocket(port);
socket.setBroadcast(true);
// Receive datagram
byte[] buffer = new byte[4096];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
// Extract message
String message = new String(packet.getData(), 0, packet.getLength());- Final Results: Broadcasting quiz results to all clients
- Network Announcement: Notifying all clients simultaneously
| Feature | TCP | UDP |
|---|---|---|
| Connection | Connection-oriented | Connectionless |
| Reliability | Reliable | Unreliable |
| Speed | Slower | Faster |
| Ordering | Ordered | Unordered |
| Use Case | Quiz Q&A | Final broadcast |
✅ Fast: No connection overhead
✅ Efficient: One message reaches all clients
✅ Simple: No connection management
✅ Broadcast: Reaches all network devices
❌ No delivery guarantee
❌ No ordering guarantee
❌ No error correction
A client-server model is a distributed application structure where clients request services and servers provide them.
public class QuizMessage {
public enum MessageType {
JOIN, // Client joins quiz
QUESTION, // Server sends question
ANSWER, // Client sends answer
SCORE_UPDATE, // Server sends score
QUIZ_END, // Quiz completed
ERROR, // Error message
WAITING // Waiting for players
}
private MessageType type;
private String content;
private Object data;
}1. CLIENT → SERVER: JOIN (player name)
2. SERVER → CLIENT: WAITING (waiting for players)
3. SERVER → CLIENT: QUESTION (quiz question)
4. CLIENT → SERVER: ANSWER (selected option)
5. SERVER → CLIENT: SCORE_UPDATE (current score)
6. Repeat steps 3-5 for all questions
7. SERVER → CLIENT: QUIZ_END (final results)
8. SERVER → ALL: UDP BROADCAST (final results)
QuizMessage answerMsg = new QuizMessage(
QuizMessage.MessageType.ANSWER,
String.valueOf(answer)
);
sendMessage(answerMsg);boolean correct = quizService.checkAnswer(clientId, answer);
QuizMessage response = new QuizMessage(
QuizMessage.MessageType.SCORE_UPDATE,
correct ? "Correct!" : "Wrong!",
currentScore
);
sendMessage(response);Application Layer: Quiz Logic (Questions, Answers, Scores)
↓
Protocol Layer: JSON Message Format
↓
Transport Layer: TCP Socket (Reliable) / UDP (Broadcast)
↓
Network Layer: IP Addressing
↓
Physical Layer: Network Hardware
✅ Centralized Logic: Server controls quiz flow
✅ Scalability: Multiple clients connect to one server
✅ Separation of Concerns: Client handles UI, server handles logic
✅ Structured Communication: JSON protocol ensures consistency
1. SERVER STARTUP
├─ TCP Socket: Bind to port 5000
├─ Thread Pool: Create 10 threads
└─ UDP Socket: Prepare for broadcasting
2. CLIENT CONNECTION (TCP + Multithreading)
├─ Client connects via TCP
├─ Server creates new thread (ClientHandler)
└─ Thread handles client independently
3. PLAYER REGISTRATION (Synchronization)
├─ Client sends name
├─ Server adds player (synchronized method)
└─ Prevents duplicate entries
4. QUIZ EXECUTION (Client-Server Communication)
├─ Server broadcasts questions (TCP)
├─ Clients send answers (TCP)
├─ Server updates scores (Synchronized)
└─ Server sends score updates (TCP)
5. RESULTS BROADCASTING (UDP)
├─ Quiz ends
├─ Server sends results via TCP
└─ Server broadcasts via UDP to all
Scenario: Two clients answer the same question simultaneously
- TCP Socket: Both clients connected via reliable TCP
- Multithreading: Each client handled by separate thread
- Synchronization: Score updates are synchronized
Thread 1 (Client A): Lock → Update Score A → Unlock Thread 2 (Client B): Wait → Lock → Update Score B → Unlock - Client-Server: Server sends individual score updates
- UDP Broadcast: Final results sent to all clients
- Latency: ~1-5ms per message
- Throughput: High for reliable data
- Overhead: Higher due to acknowledgments
- Concurrent Clients: Up to 10 (configurable)
- CPU Usage: Distributed across threads
- Response Time: Minimal blocking
- Lock Contention: Minimal (short critical sections)
- Throughput: High (quick lock/unlock)
- Consistency: 100% (no race conditions)
- Latency: <1ms (no handshake)
- Throughput: Very high
- Reliability: ~99% on local network
# Check if server is listening
netstat -an | findstr :5000- Connect 5+ clients simultaneously
- Verify all clients receive questions
- Check server logs for thread creation
- Have multiple clients answer simultaneously
- Verify scores are correct (no race conditions)
- Check final scores match expected values
- Complete a quiz
- Verify all clients receive UDP broadcast
- Check broadcast message content
- Monitor network traffic
- Verify JSON message format
- Check bidirectional communication
After implementing this project, you understand:
✅ How to create TCP server and client sockets
✅ How to handle multiple clients with threads
✅ How to synchronize shared resources
✅ How to broadcast data using UDP
✅ How to design client-server protocols
✅ How to integrate multiple networking concepts
✅ How to build real-world networked applications
When explaining to your instructor:
- Start with Architecture: Show the overall system design
- Explain Each Concept: Use code examples
- Demonstrate Live: Run the application
- Show Code: Point out key implementations
- Discuss Challenges: Mention synchronization issues solved
- Explain Benefits: Why each concept is important
- TCP: Reliable communication for critical data (questions/answers)
- UDP: Fast broadcasting for non-critical data (final results)
- Multithreading: Enables concurrent client handling
- Synchronization: Prevents data corruption
- Client-Server: Clean separation of concerns
This project demonstrates practical, real-world application of network programming concepts! 🎉