Of course! Here is a comprehensive guide to using TCP sockets in Java, covering both the server and client sides, with detailed explanations and complete, runnable code examples.

What is a TCP Socket?
A socket is one endpoint of a two-way communication link between two programs running on the network. The TCP (Transmission Control Protocol) is a connection-oriented protocol, meaning it establishes a reliable, ordered, and error-checked connection before any data is sent.
Think of it like a phone call:
- Dialing (Client connects to Server): The client tries to establish a connection.
- Answering (Server accepts connection): The server "picks up the phone."
- Conversation (Data Exchange): Both parties can send and receive messages.
- Hanging Up (Closing the connection): Either party can end the call.
Core Java Classes for TCP Sockets
Java's networking API is primarily in the java.net package.
| Class | Role |
|---|---|
java.net.ServerSocket |
Used by the server to listen for incoming client connections. It's like a receptionist waiting for calls. |
java.net.Socket |
Represents the connection between the client and the server. Once a connection is established, both the client and server use a Socket object to send and receive data. |
java.net.InetAddress |
Represents an IP address. You use it to specify the host (e.g., "localhost", "127.0.0.1", or a domain name) to connect to. |
java.io.InputStream / java.io.OutputStream |
Used for reading bytes from and writing bytes to the socket's connection. |
java.io.BufferedReader / java.io.PrintWriter |
More convenient, higher-level classes for reading text lines and writing text, respectively. They are often "wrapped" around the stream from the socket. |
The Server Side (ServerSocket)
The server's job is to wait for a client to connect and then handle that connection.

Steps for the Server:
- Create a
ServerSocket: Specify a port number (e.g.,1234). The server will listen on this port. - Accept a Connection: Call
serverSocket.accept(). This method blocks (pauses the program) until a client connects. When a client connects, it returns aSocketobject representing the connection to that specific client. - Set up I/O Streams: Get the
InputStreamandOutputStream(or more commonly,BufferedReaderandPrintWriter) from the returnedSocket. - Communicate: Use the streams to read data from the client and send data back.
- Close the Connection: Close the
Socketand the streams when done.
Complete Server Code (EchoServer.java)
This server will listen for a client, receive a message, print it, and send back an acknowledgment.
// EchoServer.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class EchoServer {
public static void main(String[] args) {
int port = 1234; // The port number the server will listen on
// Using try-with-resources to automatically close the ServerSocket
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Server is listening on port " + port);
// The accept() method waits (blocks) until a client connects
Socket clientSocket = serverSocket.accept();
System.out.println("Client connected: " + clientSocket.getInetAddress().getHostAddress());
// Set up I/O streams
// PrintWriter for sending text to the client
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
// BufferedReader for reading text from the client
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
// Read from the client until the client closes the connection
while ((inputLine = in.readLine()) != null) {
System.out.println("Received from client: " + inputLine);
// Send a response back to the client
out.println("Server: Message received -> " + inputLine);
}
System.out.println("Client disconnected.");
} catch (IOException e) {
System.out.println("Server exception: " + e.getMessage());
e.printStackTrace();
}
}
}
The Client Side (Socket)
The client's job is to initiate a connection to the server and then communicate.
Steps for the Client:
- Create a
Socket: Specify the server's IP address (or hostname) and port number. This constructor blocks until the connection is successfully established or an exception is thrown. - Set up I/O Streams: Get the
InputStreamandOutputStreamfrom theSocket. - Communicate: Use the streams to send data to the server and read data back.
- Close the Connection: Close the
Socketand the streams when done.
Complete Client Code (EchoClient.java)
This client will connect to the server, send a message, and read the server's response.
// EchoClient.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class EchoClient {
public static void main(String[] args) {
String hostname = "localhost"; // The server's address
int port = 1234; // The port the server is listening on
// Using try-with-resources to automatically close the socket and streams
try (
Socket socket = new Socket(hostname, port);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))
) {
System.out.println("Connected to the server.");
System.out.print("Enter a message (or 'exit' to quit): ");
String userInput;
// Read from the user's console
while ((userInput = stdIn.readLine()) != null) {
if ("exit".equalsIgnoreCase(userInput)) {
break;
}
// Send the user's message to the server
out.println(userInput);
// Read the server's response
String response = in.readLine();
System.out.println("Server response: " + response);
System.out.print("Enter a message (or 'exit' to quit): ");
}
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + hostname);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to " +
hostname + ". Is the server running?");
System.exit(1);
}
}
}
How to Run the Example
-
Save the files: Save the two code blocks above as
EchoServer.javaandEchoClient.javain the same directory.
(图片来源网络,侵删) -
Compile the code: Open a terminal or command prompt in that directory and run the Java compiler.
javac EchoServer.java EchoClient.java
-
Run the Server: In the same terminal, start the server. It will wait for a connection.
java EchoServer
You should see the output:
Server is listening on port 1234 -
Run the Client: Open a new terminal or command prompt (leave the server running in the first one). Start the client.
java EchoClient
You should see:
Connected to the server.followed by the promptEnter a message (or 'exit' to quit): -
Interact:
- Type a message in the client's terminal and press Enter.
- The server's terminal will print the received message.
- The client's terminal will print the server's response.
- Type
exitin the client's terminal to close the connection and exit the program. - The server will then print
Client disconnected.and will wait for a new connection.
Important Considerations and Best Practices
-
Blocking I/O: The basic
SocketandServerSocketuse blocking I/O. Theaccept()andread()methods pause the program until an event occurs. This is simple but inefficient for handling many clients simultaneously. For real-world applications, you would typically use:- Multithreading: Create a new thread for each client connection.
- Non-blocking I/O (
java.nio): A more scalable, modern approach. - Asynchronous I/O (
CompletableFuture,AsSocketChannel): A more advanced, event-driven model.
-
Resource Management: Network resources (sockets, streams) are limited and must be closed properly. The try-with-resources statement is the best way to ensure this happens automatically, even if exceptions occur.
-
Ports: Ports below 1024 are "privileged" and usually require administrator rights to bind to. Use ports from 1024 to 49151 for applications.
-
Data Serialization: The examples above send simple text (strings). If you need to send complex objects (like custom classes), you should use ObjectOutputStream and ObjectInputStream. The classes you send must implement the
Serializableinterface.
