Establishing Dual Server Connections in Java
A common scenario in distributed systems involves a Java application acting as a client to two separate servers, or one server process that needs to accept connections from two disitnct clients. The core mechanism relies on the ServerSocket class for accepting incoming connections and the Socket class for initiating connections.
Workflow Overview
- Instantiate two
ServerSocketinstances bound to different ports. - Create two
Socketobjects pointing to the respective server addresses. - Initiate the client connections to the remote servers.
- Accept the connections on the server side.
- Exchange data over the established channels.
Implementation Steps
Step 1 – Initialize Server Sockets
ServerSocket primaryServer = new ServerSocket(8080);
ServerSocket secondaryServer = new ServerSocket(9090);
The two server sockets listen independently on the specified ports, ready to accept incoming Socket connections.
Step 2 – Create Client Sockets and Connect
Socket clientA = new Socket();
clientA.connect(new InetSocketAddress("192.168.10.100", 8080), 5000);
Socket clientB = new Socket("192.168.10.200", 9090);
clientA uses a no-arg constructor and explicitly connects with a timeout. clientB performs the connection directly in the constructor.
Step 3 – Accept Remote Connections
Socket serverConnA = primaryServer.accept();
Socket serverConnB = secondaryServer.accept();
Each call to accept() blocks until a client connection is received and returns a dedicated Socket for communication.
Step 4 – Transfer Data
Once connections are established, input and output streams are obtained from each Socket:
// For serverConnA (reading from client)
BufferedReader readerA = new BufferedReader(new InputStreamReader(serverConnA.getInputStream()));
PrintWriter writerA = new PrintWriter(serverConnA.getOutputStream(), true);
// For clientB (sending to server)
PrintWriter writerB = new PrintWriter(clientB.getOutputStream(), true);
BufferedReader readerB = new BufferedReader(new InputStreamReader(clientB.getInputStream()));
// Example exchange
writerB.println("Hello from client B");
String response = readerA.readLine();
Any real implementation must handle exceptions (IOException, SocketTimeoutException) and properly close all resources in a finally block or using try-with-resources.