Have you ever wondered how two applications communicate over a network? Yes, through socket programming! Whether it’s a chat application, an online multiplayer game, or even a simple file transfer tool, they all rely on one fundamental concept: socket programming. But what exactly are sockets, and how can we use them in Java to build such systems?
Java, as a robust and platform-independent language, provides a powerful set of tools to implement network communication using sockets.

This blog will break down socket programming in Java into simple, digestible steps. We’ll start by understanding the basics of sockets and how they enable bidirectional communication between a client and a server.
Then, we’ll dive into writing practical examples of a client-server interaction, showing how Java’s networking API makes this process straightforward.
By the end of this blog, you’ll have a solid understanding of how socket programming works and how you can use it to build real-world networked applications in Java. Let’s get started!
What Will You Learn?
What Will You Build?
In this blog, we gonna build a simple echo server and a client who will communicate with the server.
The interaction will look something like this –
[Client]
Starting connection...
Hello
Echo: Hello
How are you?
Echo: How are you?
Great!
Echo: Great!
[Server]
Listening to clients...
Client accepted
Client: Hello
Client: How are you?
Client: Great!
Excited to build this echo server and echo client?
Let’s jump right into how socket programming works, and we will start discussing about the code step by step.
How Socket Communication Works?
When two applications want to communicate over a network, they need a common “endpoint” to send and receive data. A socket acts as this endpoint. Think of a socket as a virtual doorway that allows data to flow between two machines.
Each socket is associated with two key pieces of information:
- An IP address: This identifies the machine on the network.
- A port number: This identifies the specific application or service running on that machine.
When communication happens, one application acts as the server, listening for incoming connections on a specific port. The other application acts as the client, initiating the connection to the server’s IP and port. Once the connection is established, the two applications can exchange data.
Following diagram explains the flow of socket communication.

Server and client has different steps that they follow when communicating, for server –
- Server Socket is created.
- Server is “bind”ed to an address (Java handles this automatically). It is necessary as client has to know which IP address the server resides.
- Server then listens for clients.
- If any clients send connection request, it will accept (if available).
- Then client and server communication starts with I/O operations.
For client, it has to –
- Create the socket.
- Send connection request to server given the IP address and port.
- Performs the I/O operations after that.
Now, you have some basic idea about how socket communication happens in general, let’s jump to the exciting part… Coding the echo server!!
Creating Server Socket
Creating server socket in java is really easy. You just need to import the necessary libraries and just use ServerSocket
to create the server socket at the given port and will automatically bind to the machine where the server is executed.
// SERVER
serverSocket = new ServerSocket(port);
The first part for the socket programming is here, now we are going to listen to clients and connect with them for communication!
Create Client Socket and Listen
Now, we need to create a socket that will be used for communication between client and server.
Remember, in Java ServerSocket
is created for the sole purpose of creating server and listening to clients at a specified port, after it finds a client it “hands-over” the connection to a Socket
that is responsible for the communication of data with client.
// [SERVER]
System.out.println("Listening to clients...");
clientSocket = serverSocket.accept();
System.out.println("Client accepted");
In the client side, we also need to create a socket that will start the communication with the server.
// [CLIENT]
System.out.println("Starting connection...");
clientSocket = new Socket(ip, port);
Now the server has accepted the client for socket communication and, finally we will dive to the main part of socket programming, which is communicating with data through I/O streams.
I/O Stream in Socket Communication
After the socket connection is established, you need to communicate between the client and server and do some I/O operations.
For that we need to initialize 3 streams – output to socket, input from socket, input from standard input.
The server and client will share an endpoint where the communication happens, in this endpoint –
- Server Input Stream <-> Client Output Stream
- Server Output Stream <-> Client Input Stream
Server socket input is the output coming from the client socket, and server output will become the input for the client socket.
// [SERVER]
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line = "";
try {
while ((line = in.readLine()) != null) {
if (line.equalsIgnoreCase("Over")) {
break;
}
System.out.println("Client: " + line);
respond(line);
}
} catch (IOException i) {
System.out.println(i);
}
// [CLIENT]
out = new PrintWriter(clientSocket.getOutputStream(), true); // Send the message to server socket
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); // To read from server
userInput = new BufferedReader(new InputStreamReader(System.in));
String message = "";
try {
while ((message = userInput.readLine()) != null) {
if (message.equalsIgnoreCase("Over")) {
break;
}
out.println(message);
String serverOutput = in.readLine();
System.out.println(serverOutput);
}
} catch (IOException i) {
System.out.println(i);
}
In this communication, we are iterating over all the messages that the client is sending and just sending the same message back with Echo:
appended to the beginning.
We close the I/O operation when client types “Over”.
In socket programming, it is important that you close the sockets and other streams of input/output. That is what we gonna do next!
Stop Socket Communication
It is important that you close the communication channels between client and socket, and you can do that easily by using close
.
// [SERVER]
try {
serverSocket.close();
clientSocket.close();
in.close();
out.close();
} catch (IOException i) {
System.out.println(i);
}
// [CLIENT]
try {
in.close();
out.close();
userInput.close();
clientSocket.close();
} catch (IOException i) {
System.out.println(i);
}
Final Echo Server and Echo Client
The final code will look like the following in Java –
// EchoServer.java
import java.net.*;
import java.io.*;
public class EchoServer {
private ServerSocket serverSocket;
private Socket clientSocket;
private PrintWriter out;
private BufferedReader in;
public void start(int port) {
try {
serverSocket = new ServerSocket(port);
System.out.println("Listening to clients...");
clientSocket = serverSocket.accept();
System.out.println("Client accepted");
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line = "";
try {
while ((line = in.readLine()) != null) {
if (line.equalsIgnoreCase("Over")) {
break;
}
System.out.println("Client: " + line);
respond(line);
}
} catch (IOException i) {
System.out.println(i);
}
stop();
} catch (IOException i) {
System.out.println(i);
}
}
public void respond(String message) {
out.println("Echo: " + message);
}
public void stop() {
try {
serverSocket.close();
clientSocket.close();
in.close();
out.close();
} catch (IOException i) {
System.out.println(i);
}
}
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Format: java server 6666");
return;
}
int port = Integer.parseInt(args[0]);
EchoServer server = new EchoServer();
server.start(port);
server.stop();
}
}
// EchoClient.java
import java.net.*;
import java.io.*;
public class EchoClient {
private Socket clientSocket;
private PrintWriter out;
private BufferedReader in;
public BufferedReader userInput;
public void startConnection(String ip, int port) {
try {
System.out.println("Starting connection...");
clientSocket = new Socket(ip, port);
out = new PrintWriter(clientSocket.getOutputStream(), true); // Send the message to server socket
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); // To read from server
userInput = new BufferedReader(new InputStreamReader(System.in));
} catch (UnknownHostException u) {
System.out.println(u);
} catch (IOException i) {
System.out.println(i);
}
}
public void sendMessages() {
String message = "";
try {
while ((message = userInput.readLine()) != null) {
if (message.equalsIgnoreCase("Over")) {
break;
}
out.println(message);
String serverOutput = in.readLine();
System.out.println(serverOutput);
}
} catch (IOException i) {
System.out.println(i);
}
}
public void stopConnection() {
try {
in.close();
out.close();
userInput.close();
clientSocket.close();
} catch (IOException i) {
System.out.println(i);
}
}
public static void main(String[] args) {
if (args.length < 2) {
System.out.println("Format: java EchoClient 127.0.0.1 6666");
return;
}
EchoClient client = new EchoClient();
String ip = args[0];
int port = Integer.parseInt(args[1]);
client.startConnection(ip, port);
client.sendMessages();
client.stopConnection();
}
}
To get the final output, run the following commands in 2 different terminals –
javac EchoServer.java // This will generate class file
java EchoServer 6666 // This will run the server at port 6666
javac EchoClient.java
java EchoClient 127.0.0.1 6666 // This will connect to local server at port 6666
Conclusion
Socket programming in Java provides a powerful way to enable communication between two applications over a network.
In this blog, we explored how socket communication happens, focusing on the server-client model.
Socket programming is a fundamental building block for many networked applications, from chat systems to multiplayer games. If you’re new to this, try building a simple client-server application to strengthen your understanding.
For your next steps, you can explore handling multiple clients using threads, implementing secure socket communication (SSL), or building higher-level protocols over sockets.
Want to read some more blogs from me? Start from this blog.
Happy Coding💻
References: