Building TCP Servers with ServerSocket: Multi-Client Handling Strategies
Building TCP Servers with ServerSocket: Multi-Client Handling Strategies
Introduction to TCP Server
जब हम network communication की बात करते हैं, तो TCP (Transmission Control Protocol) एक बहुत ही important concept है। यह एक connection-oriented protocol होता है, जो client और server के बीच reliable communication प्रदान करता है।
Java में TCP Server बनाने के लिए ServerSocket class का use किया जाता है। यह class server-side पर connection accept करने के लिए responsible होती है।
Simple शब्दों में कहें तो — ServerSocket का काम है clients के connection requests को listen करना और उन्हें handle करना। जैसे ही कोई client connect होता है, server उसके लिए एक अलग Socket object create करता है ताकि दोनों के बीच data exchange हो सके।
What is ServerSocket?
Java में ServerSocket एक class है जो TCP server application को clients से incoming connections accept करने की सुविधा देती है।
जब कोई server start होता है, तो वह एक specific port पर listen करता है। Client उसी port पर connect करता है ताकि communication start हो सके।
Basic Syntax:
ServerSocket server = new ServerSocket(portNumber);
Socket socket = server.accept();
ऊपर दिए code में, ServerSocket एक port पर listen कर रहा है। जैसे ही कोई client connect करेगा, accept() method return होगा और एक नया Socket object देगा जिससे communication start हो सके।
Working of TCP Server
एक TCP Server का basic working process कुछ इस तरह होता है:
- Server किसी fixed port number पर listen करता है।
- Client उसी port पर connection request भेजता है।
- Server request accept करता है और एक नया socket create करता है।
- Server और client input/output streams के ज़रिए data exchange करते हैं।
- Communication complete होने के बाद socket close कर दिया जाता है।
ये process हर client के लिए अलग-अलग sockets के ज़रिए होती है, जिससे simultaneous communication possible होता है।
Single Client Server Example
सबसे पहले देखते हैं कि एक simple TCP server कैसे काम करता है जो एक single client को handle करता है।
Server Code:
import java.io.*;
import java.net.*;
public class SimpleServer {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(5000);
System.out.println("Server started. Waiting for client...");
Socket socket = server.accept();
System.out.println("Client connected.");
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter output = new PrintWriter(socket.getOutputStream(), true);
String message = input.readLine();
System.out.println("Client says: " + message);
output.println("Hello from server!");
socket.close();
server.close();
}
}
Client Code:
import java.io.*;
import java.net.*;
public class SimpleClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 5000);
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
PrintWriter output = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.print("Enter message: ");
String msg = input.readLine();
output.println(msg);
System.out.println("Server: " + in.readLine());
socket.close();
}
}
यह basic model एक single client connection को handle करता है। लेकिन real-world applications में multiple clients connect होते हैं, इसलिए हमें multi-client handling की strategy चाहिए।
Multi-Client Handling Strategies
जब एक से अधिक clients को एक साथ connect होना होता है, तो server को multi-threaded बनाना पड़ता है। हर client के लिए एक नया thread create किया जाता है, ताकि सभी clients एक साथ communicate कर सकें।
Approach 1: Thread per Client
इस approach में हर बार जब कोई नया client connect करता है, server एक नया thread create करता है। यह सबसे common और easy approach है।
Example:
import java.io.*;
import java.net.*;
class ClientHandler extends Thread {
Socket socket;
ClientHandler(Socket socket) {
this.socket = socket;
}
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
String message;
while ((message = in.readLine()) != null) {
System.out.println("Client: " + message);
out.println("Server received: " + message);
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class MultiClientServer {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(5000);
System.out.println("Server started...");
while (true) {
Socket socket = server.accept();
System.out.println("New client connected!");
new ClientHandler(socket).start();
}
}
}
इस approach में हर client को एक अलग thread मिलता है। इसका फायदा यह है कि हर client independent तरीके से काम करता है। लेकिन अगर बहुत सारे clients connect हो जाएँ, तो threads बहुत बढ़ जाते हैं, जिससे performance issue आ सकता है।
Advantages:
- Implementation आसान और direct है।
- हर client को separate service मिलती है।
Disadvantages:
- Too many threads create होने पर memory usage बढ़ता है।
- Server overloaded हो सकता है।
Approach 2: Thread Pooling (Executor Service)
इस approach में server एक limited number of threads maintain करता है। जब कोई नया client connect होता है, तो उसे pool में available thread assign कर दिया जाता है। इससे system resources controlled रहते हैं।
import java.io.*;
import java.net.*;
import java.util.concurrent.*;
public class ThreadPoolServer {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(5000);
ExecutorService pool = Executors.newFixedThreadPool(5);
System.out.println("Server started...");
while (true) {
Socket socket = server.accept();
pool.execute(new ClientHandler(socket));
}
}
}
यह approach scalable और efficient होती है क्योंकि यह system resources को control में रखती है।
Handling Communication Between Clients
कभी-कभी server को clients के बीच communication enable करना पड़ता है, जैसे chat applications में होता है। इसके लिए server सभी connected clients की list maintain करता है और जब कोई message आता है, तो वह बाकी clients को broadcast करता है।
Concept Diagram:
Server — multiple clients से connect होता है। जब कोई client message भेजता है, तो server उस message को सभी connected clients को भेज देता है।
Important Classes and Methods
| Class/Method | Description |
|---|---|
ServerSocket | Server को port पर bind करता है और incoming connections accept करता है। |
accept() | Client के connect होने का इंतजार करता है और एक नया Socket return करता है। |
Socket | Server और Client के बीच communication channel बनाता है। |
InputStreamReader | Byte stream को character stream में convert करता है। |
PrintWriter | Output stream पर data भेजने के लिए use होता है। |
Best Practices for Multi-Client Server
- Always close socket connections properly to avoid memory leaks।
- Use
try-with-resourcesfor automatic resource management। - Handle exceptions gracefully ताकि server crash न हो।
- Log every client connection and message activity।
- Use thread pool instead of creating unbounded threads।
Real World Applications
- Chat Servers (WhatsApp, Discord जैसे systems)
- Online Multiplayer Games
- Remote File Access Systems
- Distributed Computing Applications
- IoT Device Communication Servers
Summary of Learning
इस पूरे topic में हमने देखा कि कैसे ServerSocket का use करके एक TCP Server बनाया जाता है और multiple clients को efficiently handle किया जा सकता है। Multi-client handling strategies जैसे “Thread per client” और “Thread pool” approach server की scalability और performance बढ़ाती हैं।
Exam Specific Notes
- ServerSocket class TCP server बनाने के लिए use होती है।
- accept() method client connection accept करता है।
- हर client को अलग Socket object मिलता है।
- Thread per client approach simple है लेकिन heavy load पर inefficient होती है।
- Thread pool approach ज्यादा scalable होती है।
- Communication के लिए InputStreamReader और PrintWriter का use होता है।
- Always close sockets and streams properly।