Question
How to handle multiple clients connecting to a single server in socket programming?
import javax.net.ssl.*;
import javax.net.*;
import java.io.*;
import java.net.*;
public class LogServer {
private static final int PORT_NUM = 5000;
public static void main(String args[]) {
ServerSocketFactory serverSocketFactory =
ServerSocketFactory.getDefault();
ServerSocket serverSocket = null;
try {
serverSocket =
serverSocketFactory.createServerSocket(PORT_NUM);
} catch (IOException ignored) {
System.err.println("Unable to create server");
System.exit(-1);
}
System.out.printf("LogServer running on port: %s%n", PORT_NUM);
while (true) {
Socket socket = null;
try {
socket = serverSocket.accept();
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(
new InputStreamReader(is, "US-ASCII"));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException exception) {
// Just handle next request.
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException ignored) {
}
}
}
}
}
}
Answer
To enable multiple clients to connect to one server in socket programming, you need to handle each client's connection in a separate thread. The given LogServer.java implementation currently processes one client at a time; it requires modification to accommodate concurrent client connections.
import javax.net.ssl.*;
import javax.net.*;
import java.io.*;
import java.net.*;
public class LogServer {
private static final int PORT_NUM = 5000;
public static void main(String args[]) {
ServerSocketFactory serverSocketFactory =
ServerSocketFactory.getDefault();
ServerSocket serverSocket = null;
try {
serverSocket =
serverSocketFactory.createServerSocket(PORT_NUM);
} catch (IOException ignored) {
System.err.println("Unable to create server");
System.exit(-1);
}
System.out.printf("LogServer running on port: %s%n", PORT_NUM);
while (true) {
try {
Socket socket = serverSocket.accept();
// Handle each client in a new thread
new ClientHandler(socket).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class ClientHandler extends Thread {
private Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
public void run() {
try (InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "US-ASCII"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException ignored) {}
}
}
}
Causes
- The server is only processing one connection in a blocking manner.
- When a client connects, the server waits for that connection to close before accepting new ones.
Solutions
- Use multithreading to handle each client connection separately.
- For each accepted socket, create a new thread that processes the communication with that specific client.
Common Mistakes
Mistake: Not using multithreading, causing the server to handle a single connection at a time.
Solution: Implement a separate thread for each client connection using the thread class or implement runnable.
Mistake: Immediate socket closure without handling exceptions properly.
Solution: Ensure graceful handling and logging of exceptions during socket operations.
Helpers
- socket programming
- Java server multiple clients
- multithreaded server example
- handle client connections
- Java socket example