Java Socket Programming
In this page:
ServerSocket Basics
ServerSocket is the class you use to write server applications: it binds to and listens on a specific port, then blocks on accept() until a client connects. Understanding that accept() blocks is important, because a naive server will only ever be able to talk to one client at a time unless you hand connections off to other threads.
Example: ServerSocket Basics
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(0); // OS picks a free port
new Thread(() -> {
try (Socket client = server.accept()) { // blocks until a client connects
System.out.println("Client connected");
} catch (Exception e) {}
}).start();
new Socket("localhost", server.getLocalPort());
Thread.sleep(100);
server.close();
}
}
Login to try C/C++/Java/PHP code in the editor
Socket Client Basics
The Socket class represents a client-side connection to a server. You connect by supplying the server's hostname and port to its constructor, at which point Java performs the TCP handshake and gives you input/output streams to actually exchange data.
Example: Socket Client Basics
import java.net.*;
public class Main {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(0);
new Thread(() -> { try { server.accept(); } catch (Exception e) {} }).start();
Socket client = new Socket("localhost", server.getLocalPort()); // TCP handshake happens here
System.out.println("Connected: " + client.isConnected());
client.close();
server.close();
}
}
Login to try C/C++/Java/PHP code in the editor
Bidirectional Socket Communication
You can establish bidirectional communication by starting a ServerSocket in a background thread so it can accept connections without blocking the rest of your program, then connecting a client Socket to it from elsewhere. Once connected, both sides read and write independently over the same underlying TCP connection.
Example: Bidirectional Socket Communication
import java.net.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(0);
Thread serverThread = new Thread(() -> {
try (Socket s = server.accept()) {
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println("Server received: " + in.readLine());
new PrintWriter(s.getOutputStream(), true).println("reply");
} catch (Exception e) {}
});
serverThread.start();
Socket client = new Socket("localhost", server.getLocalPort());
new PrintWriter(client.getOutputStream(), true).println("hello");
BufferedReader clientIn = new BufferedReader(new InputStreamReader(client.getInputStream()));
System.out.println("Client received: " + clientIn.readLine());
client.close();
server.close();
}
}
Login to try C/C++/Java/PHP code in the editor
Multi-Threaded Server
To handle multiple clients simultaneously, a well-designed server delegates each accepted connection to its own thread (or a thread-pool task) rather than processing it inline on the accept loop. Without this, a single slow or hanging client would stall every other client waiting to be served.
Example: Multi-Threaded Server
import java.net.*;
public class Main {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(0);
Runnable acceptLoop = () -> {
try {
for (int i = 0; i < 2; i++) {
Socket client = server.accept();
new Thread(() -> System.out.println("Handling a client on its own thread")).start(); // delegated, not inline
client.close();
}
} catch (Exception e) {}
};
new Thread(acceptLoop).start();
new Socket("localhost", server.getLocalPort()).close();
new Socket("localhost", server.getLocalPort()).close();
Thread.sleep(100);
server.close();
}
}
Login to try C/C++/Java/PHP code in the editor
Closing Sockets Safely
Always close socket streams and connection resources once you're done with them, since leaked sockets can exhaust a server's available file descriptors under load. The try-with-resources statement handles this cleanup automatically, closing sockets and streams even if an exception is thrown mid-operation.
Example: Closing Sockets Safely
import java.net.*;
public class Main {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(0);
new Thread(() -> { try { server.accept().close(); } catch (Exception e) {} }).start();
try (Socket client = new Socket("localhost", server.getLocalPort())) { // try-with-resources closes automatically
System.out.println("Connected and will auto-close");
}
server.close();
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 4 topics to unlock
0/4 topics done
Complete these topics first: