Sockets basics in Java
Socket/ServerSocket, client-server model, blocking I/O.
A switchboard and phone lines
A **ServerSocket is a switchboard listening on a port. accept() blocks until a client calls, then returns a Socket — one end of a TCP connection** — for that conversation. A client simply creates new Socket(host, port).
Talking through streams
Each side reads and writes through the socket's **getInputStream() and getOutputStream()** — the same byte streams you already know, usually wrapped in readers and writers.
try (var s = new Socket("localhost", 8080);
var in = new BufferedReader(
new InputStreamReader(
s.getInputStream()))) {
System.out.println(in.readLine());
}Blocking I/O
Classic socket I/O blocks: a thread waiting in accept() or read() does nothing else until a client connects or data arrives (or the connection closes).
The silent second client
A server loop accepts a client and reads from it until it disconnects. Why does a second client get no response?
Think about it, then reveal the answer
The only thread is blocked reading from the first client, so it **never gets back to accept(). Handle each accepted Socket on its own thread — Java 21's virtual threads** make one-thread-per-client cheap.
Serving many clients
while (true) {
Socket client = server.accept();
new PrintWriter(client.getOutputStream(),
true).println("hello");
}The Socket is never closed, so OS handles pile up until the server runs out.
while (true) {
try (Socket client = server.accept()) {
new PrintWriter(client
.getOutputStream(), true)
.println("hello");
}
}try-with-resources releases each connection.
TCP vs UDP
TCP uses Socket/ServerSocket. Which class sends UDP packets?
SocketDatagramSocketHttpClient
Show the answer
**DatagramSocket** (with DatagramPacket). UDP sends independent packets without a connection — fast, but with no delivery guarantee.
Under every request
You rarely write raw sockets at work, but every HTTP call, database driver and message broker client is built on them. Knowing that blocking reads tie up threads explains connection-pool exhaustion, timeouts, and why virtual threads were such big news.
Key takeaways
- ServerSocket listens; accept() returns one Socket per client
- Socket = one end of a TCP connection
- Classic I/O blocks: a thread waits on accept/read
- Handle each client on its own (virtual) thread
Ports below 1024 are "privileged" on Unix-like systems — that's why development servers usually pick ports like 8080 instead of 80.
Practice questions
A simple server loop accepts a client and reads from it until the client disconnects. A second client connects but gets no response. Why?
- The port can only accept one client in Java
- The single thread is blocked serving the first client and never reaches accept() again
- The second client must use a different port
- TCP drops the second connection automatically
Check your answer
The single thread is blocked serving the first client and never reaches accept() again. Blocking reads hold the thread until the client sends data or leaves. Handle each accepted Socket on its own thread — virtual threads (Java 21) make this cheap.
Which JDK class do you use for UDP instead of TCP?
- Socket
- DatagramSocket
- ServerSocket
- HttpClient
Check your answer
DatagramSocket. UDP sends independent packets (datagrams) without a connection, using DatagramSocket and DatagramPacket. Socket and ServerSocket are for TCP streams.