📁 I/O, Files & Networking · Intermediate

Sockets basics in Java

Socket/ServerSocket, client-server model, blocking I/O.

🧩 The mysteryYour tiny chat server works perfectly with one user. The second user connects… and hears nothing, forever. The code has no bug you can see. What's holding them up?

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).

🤔 Think first

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

✗ Leaks a handle per client
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.

✓ Closes every connection
while (true) {
    try (Socket client = server.accept()) {
        new PrintWriter(client
            .getOutputStream(), true)
            .println("hello");
    }
}

try-with-resources releases each connection.

🔮 Predict it

TCP vs UDP

TCP uses Socket/ServerSocket. Which class sends UDP packets?

  1. Socket
  2. DatagramSocket
  3. HttpClient
Show the answer

**DatagramSocket** (with DatagramPacket). UDP sends independent packets without a connection — fast, but with no delivery guarantee.

💼 In the real world

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

  1. ServerSocket listens; accept() returns one Socket per client
  2. Socket = one end of a TCP connection
  3. Classic I/O blocks: a thread waits on accept/read
  4. Handle each client on its own (virtual) thread
🤯 Did you know?

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?

  1. The port can only accept one client in Java
  2. The single thread is blocked serving the first client and never reaches accept() again
  3. The second client must use a different port
  4. 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?

  1. Socket
  2. DatagramSocket
  3. ServerSocket
  4. HttpClient
Check your answer

DatagramSocket. UDP sends independent packets (datagrams) without a connection, using DatagramSocket and DatagramPacket. Socket and ServerSocket are for TCP streams.

Next: the non-blocking alternative — NIO channels, buffers and selectors.