Hello guys, if you want to create client server application in Java then you need to learn Java networking API an classes like Socket and ServerSocket. In the past, I have showed you how to create an HTTP Client and Server in Java where I talked about these classes. In this Java networking tutorial, we will learn how to create a simple TCP server and Client in Java using networking classes provided by JDK in java.net package. Earlier, I have showed you how to create HTTP Server, which is actually a TCP/IP Server but here we'll do it again, along with writing a TCP client as well. Though you can test your TCP server using telnet, I'll show you how to connect to it using a TCP client written in Java.
How to Create TCP Server in Java?
Creating a TCP Server in Java is not that difficult, all you need to do is create an instance of ServerSocket class and give it a port where it can listen for incoming client connection as shown below:
// opening a ServerSocket
ServerSocket server = new ServerSocket(9999);
System.out.println("Listening on port 9999 ....");
Now, if you want to keep your server alive, you need to insure that the main thread which is running this application should not finish and for that you can create an infinite loop using while(true)
Now the logic to accept the client connection and how to respond is inside the loop:
while(true){
// waiting for client to connect
// accept() will block until client connects, when connected
// a TCP socket is returned to communicate with client.
Socket clientSocket = server.accept();
System.out.println("client connected: " + clientSocket.getRemoteSocketAddress());
You can see that we are using accept() method of ServerSocket class to accept client connection. This is a blocking method and main thread will be blocked until a client connect.
Once a client is connected we open an InputStream to read the message sent by client as shown below:
// opening InputStream from Socket to read data
// send by client, wrapping it into BufferedReader
// for efficient and line by line reading
BufferedReader bfr = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
// reading message sent by client
String message = bfr.readLine();
// printing message sent by client
System.out.println("received from client : " + message);
Once we got the client message we can decide what we want to do like saving data in database or sending to another application. In this case, we have created an EchoServer so server will just send the same message to client as shown below:
// opening OutputStream on client socket to write response
OutputStream os = clientSocket.getOutputStream();
// printing message we are going to send to client
System.out.println("sent to client : " + message);
// writing into outputstream, this wil go to client
os.write(message.getBytes());
// closing the client socket, server is still running
clientSocket.close();
Here we have used OutputStream to write the data back to the client and after that we have closed the client connection. You can see that Client Connection is represented by Socket object while Server is represented by ServerSocket object.
How to create TCP Client in Java?
The steps to create a client is very similar to creating a TCP server, except that we will use Socket class instead of ServerSocket. It also accept a host and port to connect to server as shown below:
Socket toServer = new Socket("127.0.0.1", 9999);
Since our server is running on same machine we can use loopback IP address 127.0.0.1 or even localhost which resolves to this IP address. The port is the same port where our server is listening.
Once you connect to the server, you send a message by writing data into an OutputStream as shown below:
String message = "message-"+i +"\n";
System.out.println("Sending message to server : " + message);
// writing into output stream, thsi will go to server
toServer.getOutputStream().write(message.getBytes());
And then its time to read response from server and for that we use InputStream as shown below:
// opening input stream on client socket to read server's response
BufferedReader bfr= new BufferedReader(new InputStreamReader(toServer.getInputStream()));
// reading server's response
String fromServer = bfr.readLine();
System.out.println("Message received from TCP Server : " + fromServer);
// closing the TCP socket connected to server
toServer.close();
Once we got the response we read it line by line using BufferedReader's readLine() method and then we print that message and close the Socket connection.
Now, let's see how we can test this TCP client and Server program.
How to test Client Server App in Java?
In order to test this application here are the steps you can follow:
1) Start the TCP Server
2) Start the client
3) check the log messages on client and server console
Since these are Java programs you can start them directly at your IDE or if you are running from command prompt then you can use java command to run them. In below diagram I have shown a EchoServer whish shows that server return same message what is client is sending, just like our program.
TCP Client and Server Example in Java
Here is the complete code of TCP Client and Server in Java, you can copy paste this code in your favorite IDE like IntelilJIDEA or Eclipse and then run the program, first server and then client and see how it works
package test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* A Simple TCP Server in Java, which act as EchoServer
* echo the message sent by client.
* @author Javin Paul
*
*/
public class TCPServer {
public static void main(String[] args) throws IOException, InterruptedException{
System.out.println("Starting TCP Server ...");
// opening a ServerSocket
ServerSocket server = new ServerSocket(9999);
System.out.println("Listening on port 9999 ....");
while(true){
// waiting for client to connect
// accept() will block until client connects, when connected
// a TCP socket is returned to communicate with client.
Socket clientSocket = server.accept();
System.out.println("client connected: " + clientSocket.getRemoteSocketAddress());
// opening InputStream from Socket to read data
// send by client, wrapping it into BufferedReader
// for efficient and line by line reading
BufferedReader bfr = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
// reading message sent by client
String message = bfr.readLine();
// printing message sent by client
System.out.println("received from client : " + message);
//TimeUnit.SECONDS.sleep(3);
// opening OutputStream on client socket to write response
OutputStream os = clientSocket.getOutputStream();
// printing message we are going to send to client
System.out.println("sent to client : " + message);
// writing into outputstream, this wil go to client
os.write(message.getBytes());
// closing the client socket, server is still running
clientSocket.close();
}
}
}
Output
Starting TCP Server ...
Listening on port 9999 ....
client connected: /127.0.0.1:64686
received from client : message-0
sent to client : message-0
clinet connected: /127.0.0.1:64687
received from client : message-1
sent to client : message-1
You can see that client sends the message-0 and server replied back with same message. You can also send "hello" and server will also reply back with same message.
Now, let's see the code of TCP Client which sends message to our TCP Server
package test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* A Simple TCP Client in Java. It connect to the Server running in
* same machine via loopback interface.
*
* @author Javin Paul
*
*/
public class TCPClient {
public static void main(String... args) throws UnknownHostException, IOException{
for(int i = 0; i<2; i++){
System.out.println("Starting TCP Client ...");
System.out.println("Connecting to TCP Server at localhost:9999");
Socket toServer = new Socket("127.0.0.1", 9999);
String message = "message-"+i +"\n";
System.out.println("Sending message to server : " + message);
// writing into output stream, thsi will go to server
toServer.getOutputStream().write(message.getBytes());
// opening input stream on client socket to read server's response
BufferedReader bfr= new BufferedReader(new InputStreamReader(toServer.getInputStream()));
// reading server's response
String fromServer = bfr.readLine();
System.out.println("Message received from TCP Server : " + fromServer);
// closing the TCP socket connected to server
toServer.close();
}
}
}
Output
Starting TCP Client ...
Connecting to TCP Server at localhost:9999
Sending message to server : message-0
Message received from TCP Server : message-0
Starting TCP Client ...
Connecting to TCP Server at localhost:9999
Sending message to server : message-1
Message received from TCP Server : message-1
TCP Client Server Error and Exception
You will be extremely lucky in programming if you don't face issue. Most of us face different kinds of errors while running even a simple program like this TCP Client and Server due to various reasons like firewall issues, port already occupied, permissions and so on.
Here are few common TCP and network connection related error you may get in Java while working on a client server application like this, important point is you must know what is causing these error and how you can address those problems.
1) You will get the "java.net.ConnectException: Connection refused: connect" error when you start the client but Server is not running
Exception in thread "main" java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at java.net.Socket.(Socket.java:425)
at java.net.Socket.(Socket.java:208)
at test.TCPClient.main(TCPClient.java:23)
If you face any other error while running this TCP client and server program or any other on your client server application, feel free to post in comments and we will solve it together.
That's all about how to create a TCP client and Server in Java. This is one of the simplest client server program you can write in Java. Our server is called EchoServer and whatever message client sends us, server just sent it back just like echoing.
If you want to further work on your networking skill the next task I suggest you to create a chat application where multiple clients can chat with each other. You can start with just two clients. Your server's job should be able to accept clients and keep those connection active unless client sends logout message.
When a client login, you can show them all other active clients and they can choose which other client or user they want to chat. In order for this to work, make sure you use a unique userid for each client.
Later you can extend this to multiple clients and then you will face performance issue because if you will be using one thread for one user model then you cannot scale well. At that time you can explore non blocking API from Java NIO and explore classes like Channels and Buffers.
By the way Java 21 also introduced Virtual Thread feature which can allows you to scale well with one thread one user model but we will see that later, on after learning about non-blocking and asynchronous communication.
All the best with the work, if you get stuck feel free to ask in comments.
Can we support multiple clients using this code?
ReplyDelete