- When a server needs to process requests concurrently, it is necessary to create a thread for each client.
- The sketch is the following :
- the "main" server waits for client connections,
- if the connection is accepted, the main server create a thread and gives it the communication socket returned by accept().
- the thread can therefore create streams and communicate with its associated client.
- So, the "main" server is never used to communicate.
- Depend on what must be done to process client requests, thread may share some data.
- If it is the case, the easiest way is to gather all shared data within a single object, instantiated by the "main" server and given to the thread constructor.
- In order to be thread-safe, all methods of this single must be protected by a mutex, and thus in Java, declared as synchronized (or with a synchronized block to protect critical instructions).
- In the following template, we assume that this shared object is an instance of class called ServerData.
- This class must be written according to the server needs.
- The code of the "main" server:
import java.io.*;
import java.net.*;
class ServerTCP {
private ServerSocket sockConn;
private int id;
private ServerData data; // the shared object between threads
public ServerTCP(int port) throws IOException {
sockConn = new ServerSocket(port);
data = new ServerData( ... );
id = 0;
}
public void mainLoop() {
while(true) {
try {
Socket sockComm = sockConn.accept();
id += 1;
ThreadServer t = new ThreadServer(id, sockComm, data);
t.start();
}
catch(IOException e) { ... }
}
}
}
- The code of the threads :
import java.io.*;
import java.net.*;
public ServerThread extends Thread {
private Socket sockComm;
private int id;
private ServerData data;
BufferedReader br; PrintStream ps;
// other attributes
public ServerThread(int id, Socket sockComm, ServerData) {
this.id = id;
this.sockComm = sockComm;
this.data = data;
// other attributes initialization
}
public void run() {
try {
// streams instantiation
requestLoop();
// close streams
}
catch(IOException e) {
System.out.println("client disconnected");
}
}
public void requestLoop() throws IOException {
// same as in the basic template
}
// methods to process requests, same as in basic template
}