Java SE 8: Getting Started with Socket Programming

 

Overview

Purpose

This tutorial shows you how to use Java Platform, Standard Edition 8 (Java SE 8) and NetBeans 8 for socket programming over TCP/IP networks.

Time to Complete

Approximately 120 minutes

Introduction

In this tutorial, you learn how to write client/server applications for lower-level network communications. In client/server applications, the server provides the service and the client uses that service. Communication takes place over the TCP/IP network, where a client program and a server program establish a connection with one another. Each program binds a socket at the end of the connection. The java.net package provides two classes: The Socket class implements the client side of the connection, and the ServerSocket class implements the server side of the connection.

Hardware and Software Requirements

Download and install the following:
  • Oracle Java SE 8 JDK from this link.
  • NetBeans 8.0 from this link.
  • PuTTY Telnet and Secure Shell (SSH) Client from this link.

Prerequisites

Before starting this tutorial, you should:

 

Creating a Java Application

In this section, you create a Java application to demonstrate socket programming in Java.

  1. In NetBeans IDE 8.0, select New Project from the File menu.

    alt description here

  2. On the Choose Project page, perform the following steps:
    1. Select Java from Categories.
    2. Select Java Application from Projects.
    3. Click Next.
  3. View Image

  4. On the Name and Location page, perform the following steps:
    1. Enter SingleClientServer as the project name.
    2. Select Create Main Class.
    3. Enter com.example.EchoServer. (The package name and the class name are implied and match the UI to create a Java project in NetBeans.)
    4. Click Finish.
  5. View Image

 A Java SE 8 project named SingleClientServer is created in NetBeans. You're now ready to use the EchoServer.java file to write a server program.

 

Creating a Server Program

In this section, you write a program named EchoServer to connect to the server. The EchoServer example creates a ServerSocket class instance to connect to the echo client. It reads input from the client and then responds to the client that requested the connection. The server echoes the input back through the socket to the client. 

The server accepts the connection from the client, binds a new socket to the same local port, and sets its remote endpoint to the client's address and port. It needs a new socket so that it can continue to listen to the original socket for connection requests when the attention needs for the connected client.

View Image

Here's an overview of how to create the simple server program:

  1. Create and open a server socket.
  2. Wait for the client request.
  3. Open an input stream and an output stream to the client.
  4. Communicate with the client.
  5. Close the streams and then close the socket.
In this example, the EchoServer class handles one client instance.
  1. In the NetBeans IDE, perform the following steps:

    1. Open the provided SingleClientServer project.
    2. Expand Source Packages, and then expand com.example.
    3. On the Projects tab, double-click EchoServer.java.
  2. Modify EchoServer.java.

    1. Create and open a server socket.

      ServerSocket serverSocket = new ServerSocket(portNumber); 

      The portNumber argument is the logical address through which the application communicates over the network. It's the port on which the server is running. You must provide the port number through which the server can listen to the client. Don't select port numbers between 0 and 1,023 because they're reserved for privileged users (that is, super user or root). Add the server socket inside the try-with-resources block.

    2. Wait for the client request.

      Socket clientSocket = serverSocket.accept();

      The accept()method waits until a client starts and requests a connection on the host and port of this server.
      When a connection is requested and successfully established, the accept()method returns a new Socket object. It's bound to the same local port, and its remote address and remote port are set to match the client's. The server can communicate with the client over this new object and listen for client connection requests.

    3. Create input and output streams to the socket.

      out = new PrintWriter(clientSocket.getOutputStream(), true);
      in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

    4. Communicate with the client.
      Receive data from the client: (inputLine = in.readLine())
      Send data to the client: out.println(inputLine);

    5. Close the stream, and then close the socket.

    The EchoServer example creates a server socket and waits for a client request. When it receives a client request, the server connects to the client and responds to it.

    Open EchoServer.java and paste in your NetBeans IDE project file.

    Here are the descriptions:

      alt description here
    • Lines 12 to 15: The if statement checks for the length of the command-line argument. If the number of arguments isn't equal to two, then it prints a system error in the console.

    • Lines 17: The first argument from the command line is received as the port number.

    • alt description here
    • Lines 18 to 21: The statement in the try-with-resources block establishes the socket connection between the client and the server and opens a PrintWriter and a BufferReader on the socket. It's advantageous to create the server socket, the client socket, and the input and output streams in the statement, because the Java runtime automatically closes the input and output streams and the server socket.

    • Lines 24 to 26: The while loop uses the readline() method  to read one line at a time from the standard input stream.
    • Lines 28 to 30: These lines show the catch block used for handling exceptions. The constructor for ServerSocket throws IOException if it can't listen on the specified port (for example, the port is being used).

  3. On the Projects tab, right-click the SingleClientServer project, select Set Configuration, and then select Customize.

  4. alt description here

  5. Perform the following steps to set the configuration:
    1. Click New.
    2. Enter Server as the configuration name.
    3. Click Browse and select com.example.EchoServer.
    4. Enter 8005 as the argument.
    5. Click OK.
    alt description here

You successfully generated a server configuration in NetBeans IDE.

 

Creating a Client Program

In this section, you write a program named EchoClient to connect to the echo server. The EchoClient example creates a socket to connect to the echo server. It reads input from the user on the standard input stream, and then forwards that text to the echo server by writing the text to the socket. The server echoes the input back through the socket to the client. The client program reads and displays the data passed from the server. The EchoClient example writes to and reads from its socket, sending data to and receiving data from the echo server.

The client knows the host name of the machine on which the server is running. It also knows the port number on which the server is listening. To make a connection request, the client tries to connect with the server on the server's machine and port. Because the client also needs to identify itself to the server, it binds to a local port number that it will use during this connection. The system typically assigns the port number.

View Image
Here's an overview of how to create the simple client program:
  1. Create and open a client socket.
  2. Open an input stream and an output stream to the socket.
  3. Read from and write to the stream according to the server's protocol.
  4. Close the streams and then close the socket.

Only step c varies from client to client, depending on the server. The other steps are the same. In this example, the EchoClient class connects with one server and handles one client instance. 

  1. In the NetBeans IDE, perform the following steps:

    1. Open the provided Client project.
    2. Expand Source Packages, and then expand com.example.
    3. On the Projects tab, double-click EchoClient.java.
  2. Modify EchoClient.java.

    1. Create and open a client socket.

      Socket echoSocket = new Socket(hostName, portNumber); 

      The hostName argument is the machine where you are trying to open a connection, and portNumber is the port on which the server is running. Don't select port numbers between 0 and 1,023 because they're reserved for privileged users (that is, super user or root). 
    2. Create the input stream and output to the socket for communicating with the server.

      PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
      BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));

    3. Read from and write to the stream according to the server's protocol.
      Receive data from the server: (userInput = stdIn.readLine())
      Send data to the server: out.println(userInput);

    4. Close the stream and then close the socket.

    Note: The Java runtime closes these resources automatically when you create them in the try-with-resources block. If you don't use try-with-resources, then you need to manually close the streams and the socket.

    The EchoClient example creates a socket, gets a connection to the server, reads input from the user, and forwards that text to the server by writing into the socket.

    Open EchoClient.java and paste in your NetBeans IDE project file.

    Here are the descriptions:

      alt description here
    • Lines 12 to 15: The if statement checks for the length of the command-line argument. If the number of arguments isn't equal to two, then it prints a system error on the console.

    • Line 16: The first argument from the command line is received as the port number.

    • alt description here
    • Line 17: The second argument from the command line is received as the port number.
    • Lines 18 to 21: The statement in the try-with-resources block establishes the socket connection between the client and the server and opens a PrintWriter and a BufferReader on the socket.

    • Lines 23 to 26: The while loop uses the readline method to read one line at a time from the standard input stream. It reads a line from the BufferedReader object stdIn, which is connected to the socket. The readline method waits until the server echoes the information back to the echoClient. When readline returns, echoClient prints the information to the standard output.

    • alt description here
    • Lines 27 to 33: Theses lines show the catch block used for handling exceptions. Here, you are handling UnknownHostException and IOException exceptions.

  3. On the Projects tab, right-click the Client project, select Set Configuration, and then select Customize.

  4. alt description here

  5. Perform the following steps to set the configuration:
    1. Click New.
    2. Enter Client as the configuration name.
    3. Click Browse and select com.example.EchoClient.
    4. Enter 127.0.0.1 8005 as the argument.
    5. Click OK.
  6. alt description here

You successfully generated a client configuration in the NetBeans IDE.

 

Running a Single Client/Server Program

  You already configured a single client and a single server. In this section, you run the client/server program. You start the server program first, and then you start the client program.

  1. On the Projects tab, right-click the SingleClientServer project, select  Set Configuration, and then select Server.

    alt description here

    You successfully set the server configuration to run the server program.

  2. Right-click the SingleClientServer project and select Run.

    alt description here
  3. Verify the output.
    alt description here 
  4. You successfully ran the server in the NetBeans IDE. After the server starts, you can start the client program.

  5. On the Projects tab, right-click the Client project, select Set Configuration, and then select Client.

    alt description here

    You successfully set the client configuration to run the client program.

  6. Right-click the Client project and select Run.

    alt description here
  7. Enter the following user input, and then press Enter: Hi. Welcome to SocketProgramming.

  8. alt description here

    The input text is echoed in the client window and displayed in the console.

  9. Switch to the server window and verify the output.
    alt description here

    The server successfully listened to the client program at local port 8005 and echoed the input message received for the client. The echo message received from the client is displayed in the console.

  10. Stop the server when you finish running the client/server application.
    alt description here

You successfully configured and executed the single client/server program.

 

Extending the Server to Implement Multiple Clients

In this section, you write a server program called Server, which connects to EchoClient.java. The Server program creates a  Serversocket, gets a connection to the echo client by using a thread instance, reads input from the client, and responds to the client that requested the connection. To keep the server example simple, you designed it to listen for and handle a single connection request.

Multiple client requests can come into the same port and, consequently, into the same Serversocket. Because client connection requests are queued at the port, the server must accept the connections sequentially. However, the server can service them simultaneously by using threads (one thread for each client connection).

Here is the basic flow of the logic in such a server program:

while (true) {
accept a connection;
create a thread to deal with the client;
}

The thread reads from and writes to the client connection as needed. 

In this example, the server class functionality is split into two classes: Server.java and RequestHandler.java. Server.java loops forever, listening for client connection requests on a ServerSocket.
  1. In the NetBeans IDE, perform the following steps:

    1. Open the provided MultiClientServer project.
    2. Expand Source Packages, and then expand com.example.
    3. On the Projects tab, double-click Server.java.
  2. Modify Server.java.

    1. Create and open a server socket.

      ServerSocket serverSocket = new ServerSocket(portNumber);

      The portNumber argument is the port on which the server is running. 

    2. Accept the connection.

      Socket clientSocket = serverSocket.accept();

    3. Create a thread object to process the client request.

      executor = Executors.newFixedThreadPool(5);

    The Server example creates a server socket, waits for a client request, and connects to the client by spawning a new thread object. In this example, you use a fixed thread pool with five threads.

    Open Server.java and paste in your NetBeans IDE project file.

    Here are the descriptions:

      alt description here
    • Lines 12 to 15: The if statement checks for the length of the command-line argument. If the number of arguments isn't equal to two, then it prints a system error in the console.

    • Line 16: The first argument from the command line is received as the port number.
    • alt description here
    • Line 18: The statement in the try-with-resources block creates the  serverSocket object.

    • Line 19: The thread pool of five threads is created by using the Executor interface.  

    • Lines 21 to 25: The while loop keeps looping to check for new client requests.    
      • Line 22: The server socket waits and accepts a connection to the client.
      • Line 23: The socket class creates the instance of the runnable interface by passing the client socket object.
      • Line 24: The runnable interface assigns the thread from the thread pool to service the worker instance.
      alt description here
    • Lines 26 to 29: You use this catch block to handle exceptions. In this example, you're handling IOException.

    • Lines 30 to 33: The finally block closes the executor if it still exists.
  3. Open and modify the provided RequestHandler.java.

    1. Implement the Runnable interface to RequestHandler.java:
      public class RequestHandler implements Runnable

    2. Create the input and output streams to the socket for communicating with the server:

      BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
      BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));

    3. Read from and write to the stream according to the server's protocol:
      Receive data from the server: (userInput = in.readLine())
      Send data to the server: writer.write("You entered : " + userInput);

    4. Close the stream and then close the socket connection.

    The RequestHandler object communicates with the client by reading from and writing to the socket. Let's look at the example program.

    Open RequestHandler.java  and paste in your NetBeans IDE project file.

    Here are the descriptions:

      alt description here
    • Line 21: The thread.start() method in Server.java calls the run()method in RequestHandler.java.

    • alt description here
    • Lines 22 and 23: The try-with-resources block creates the BufferReader and BufferWriter objects.

    • Line 24: The thread object gets the current thread instance name and prints the name in the console.

    • Lines 26 to 32: The while loop reads a line at a time from the standard input stream by using the readline method.
      • Line 27: The replaceAll()method replaces all non-alphanumeric characters with an empty string to avoid special characters.

      • Line 28: The thread instance receives the message displays in the console.

      • Line 29: The user input text is written into the buffered writer object.

      • Line 30: The writer object adds a new line in the console.

      • Line 31: The writer object flushes the buffer.
    • Lines 33 to 37: You use the catch block to handle exceptions. In this example, you're handling IOException and the generic Exception.

  4. On the Projects tab, right-click the MultiClientServer project, select Set Configuration, and then select Customize.

  5. alt description here

  6. Perform the following steps to set the configuration:
    1. Click New.
    2. Enter Server as the configuration name.
    3. Click Browse and select com.example.Server.
    4. Enter 8005 as the argument.
    5. Click OK.
    alt description here 
  7. On the Projects tab, right-click the MultiClientSocket project, select Set Configuration, and then select Server.

    alt description here

  8. To start the multiple client/server, right-click the MultiClientServer project and select Run.

    alt description here 
  9. Verify the output of the server window.
    alt description here
You successfully generated a server configuration in the NetBeans IDE and started the server.
 

Connecting to the Server by Using PuTTY as a Client

In this section, you connect to the server by using PuTTY as the client program. PuTTY is a free, open-source software that allows connection to various servers. It supports different network protocols like SSH, Telnet, and raw socket connection.

Note:
You can also use the client program that you wrote.
  1. Double-click putty.exe, and then perform the following steps:
    1. On the boot screen, enter 127.0.0.1 in the IP address field.
    2. Enter 8005 in the Port field.
    3. Enter Telnet Session in the Saved Sessions field.
    4. Click Save.
  2. alt description here
    You successfully saved the Telnet session details.

  3. Start the PuTTY Telnet connection.
    1. Select Telnet Session.
    2. Click Load to load the Telnet configuration.
    3. Click Open.
    4. alt description here

      The Putty client opens.

      alt description here

    You successfully started the PuTTY client, which is connected to the server through the socket.

  4. Note: If the server isn't running, the PuTTY client window closes automatically. Ensure that the server is running before you start the client.
  5. In the command-prompt window, enter Hi, and then press Enter.

    alt description here
  6. In the NetBeans IDE, observe your server console and verify the output.

    alt description here
  7. The first client (Client 1) successfully connected to the server, and communication between the client and server is verified. You have already started the server and opened one instance of the client through PuTTY. Let's increase the number of clients to three to observe multiple client interactions with a single server.

  8. Repeat step 2 twice to open two more clients.
    alt description here
  9. Switch to the server window in the NetBeans IDE and verify the output.
    alt description here

    The server successfully spawned two more threads (thread-2 and thread-3) to serve requests of the clients (Client 2 and Client 3) that are connected on port 8005.

  10. Enter Hello in the console of Client 2 console and press Enter. Enter Welcome in the console of Client 3 and press Enter. Verify the output.
    alt description here

    When you press Enter, the input text is echoed in the client window.

  11. Switch to the server window in the NetBeans IDE and verify the output in the console.

    alt description here

    The server received the input messages echoed from the three clients, and the echo message is displayed in the console.

 

Summary

In this tutorial, you learned to:

  • Create a Java SE project
  • Set up a PuTTY client
  • Create a single client/server program
  • Create multiple client/server programs
  • Deploy and run the client/server program.

Resources

Credits

  • Curriculum Developer: Shilpa Chetan