Multiple clients are quite often connected to a single server at the same time. Typically, a server runs constantly on a server computer, and clients from all over the Internet may want to connect to it. You can use threads to handle the server's multiple clients simultaneously . Simply create a thread for each connection. Here is how the server handles a connection:
while ( true ) { Socket socket = serverSocket.accept(); Thread thread = new ThreadClass(socket); thread.start(); }
The server socket can have many connections. Each iteration of the while loop creates a new connection. Whenever a connection is established, a new thread is created to handle communication between the server and the new client; and this allows multiple connections to run at the same time.
Listing 25.4 creates a server class that serves multiple clients simultaneously. For each connection, the server starts a new thread. This thread continuously receives input (the radius of a circle) from clients and sends the results (the area of the circle) back to them (see Figure 25.7). The client program is the same as in Listing 25.2. A sample run of the server with two clients is shown in Figure 25.8.
1 import java.io.*; 2 import java.net.*; 3 import java.util.*; 4 import java.awt.*; 5 import javax.swing.*; 6 7 public class MultiThreadServer extends JFrame { 8 // Text area for displaying contents 9 private JTextArea jta = new JTextArea(); 10 11 public static void main(String[] args) { 12 new MultiThreadServer(); 13 } 14 15 public MultiThreadServer() { 16 // Place text area on the frame 17 setLayout( new BorderLayout()); 18 add( new JScrollPane(jta), BorderLayout.CENTER); 19 20 setTitle( "MultiThreadServer" ); 21 setSize( 500 , 300 ); 22 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 23 setVisible( true ); // It is necessary to show the frame here! 24 25 try { 26 // Create a server socket 27 ServerSocket serverSocket = new ServerSocket( 8000 ); 28 jta.append( "MultiThreadServer started at " + new Date() + '\n' ); 29 30 // Number a client 31 int clientNo = 1 ; 32 33 while ( true ) { 34 // Listen for a new connection request 35 Socket socket = serverSocket.accept(); 36 37 // Display the client number 38 jta.append( "Starting thread for client " + clientNo + 39 " at " + new Date() + '\n' ); 40 41 // Find the client's host name , and IP address 42 InetAddress inetAddress = socket.getInetAddress(); 43 jta.append( "Client " + clientNo + "'s host name is " 44 + inetAddress.getHostName() + "\n" ); 45 jta.append( "Client " + clientNo + "'s IP Address is " 46 + inetAddress.getHostAddress() + "\n" ); 47 48 // Create a new task for the connection 49 HandleAClient task = new HandleAClient(socket); 50 51 // Start the new thread 52 task.start(); 53 54 // Increment clientNo 55 clientNo++; 56 } 57 } 58 catch (IOException ex) { 59 System.err.println(ex); 60 } 61 } 62 63 // Inner class 64 // Define the thread class for handling new connection 65 class HandleAClient implements Runnable { 66 private Socket socket; // A connected socket 67 68 /** Construct a thread */ 69 public HandleAClient(Socket socket) { 70 this .socket = socket; 71 } 72 73 /** Run a thread */ 74 public void run() { 75 try { 76 // Create data input and output streams 77 DataInputStream inputFromClient = new DataInputStream( 78 socket.getInputStream()); 79 DataOutputStream outputToClient = new DataOutputStream( 80 socket.getOutputStream()); 81 82 // Continuously serve the client 83 while ( true ) { 84 // Receive radius from the client 85 double radius = inputFromClient.readDouble() ; 86 87 // Compute area 88 double area = radius * radius * Math.PI; 89 90 // Send area back to the client 91 outputToClient.writeDouble(area); 92 93 jta.append( "radius received from client: " + 94 radius + '\n' ); 95 jta.append( "Area found: " + area + '\n' ); 96 } 97 } 98 catch (IOException e) { 99 System.err.println(e); 100 } 101 } 102 } 103 } |
The server creates a server socket at port 8000 (line 27) and waits for a connection (line 35). When a connection with a client is established, the server creates a new thread to handle the communication (line 49). It then waits for another connection in an infinite while loop (lines 33 “56).
The threads, which run independently of one another, communicate with designated clients. Each thread creates data input and output streams that receive and send data to a client.
This server accepts an unlimited number of clients. To limit the number of concurrent connections, you can use a thread pool with a fixed size and add tasks to the pool.