In this Java network programming tutorial, we’ll guide you how to write a client program that talks to a server using TCP/IP protocol. In the next few minutes, you will see that Java makes it easy to develop networking applications as Java was built for the Internet. The examples are very interesting: a daytime client, a Whois client, a HTTP client and a SMTP client.

 

1. Client Socket API

The Socketclass represents a socket client. You use this class to make connection to a server, send data to and read data from that server. The following steps are applied for a typical communication with the server:

1. The client initiates connection to a server specified by hostname/IP address and port number.

2. Send data to the server using an OutputStream.

3. Read data from the server using an InputStream.

4. Close the connection.

The steps 2 and 3 can be repeated many times depending on the nature of the communication.

Now, let’s study how to use the Socket class to implement these steps.

 

Initiate Connection to a Server:

To make a connection to a server, create a new Socket object using one of the following constructors:

- Socket(InetAddress address, int port)

- Socket(String host, int port)

- Socket(InetAddress address, int port, InetAddress localAddr, int localPort)

You see, it requires the IP address/hostname of the server and the port number.

With the first two constructors, the system automatically assigns a free port number and a local address for the client computer. With the third constructor, you can explicitly specify the address and port number of the client if needed. The first constructor is often used because of its simplicity.



These constructors can throw the following checked exceptions:

- IOException: if an I/O error occurs when creating the socket.

- UnknownHostException: if the IP address of the host could not be determined.

That means you have to catch (or re-throw) these checked exceptions when creating a Socket instance. The following line of code demonstrates how to create a client socket that attempts to connect to google.com at port number 80:

Socket socket = new Socket("google.com", 80)
 

Send Data to the Server:

To send data to the server, get the OutputStream object from the socket first:

OutputStream output = socket.getOutputStream();
Then you can use the write() method on the OutputStream to write an array of byte to be sent:

byte[] data = ….
output.write(data);
And you can wrap the OutputStream in a PrintWriter to send data in text format, like this:

PrintWriter writer = new PrintWriter(output, true);
writer.println(“This is a message sent to the server”);
The argument true indicates that the writer flushes the data after each method call (auto flush).

 

Read Data from the Server:

Similarly, you need to obtain an InputStream object from the client socket to read data from the server:

InputStream input = socket.getInputStream();
Then use the read() method on the InputStream to read data as an array of byte, like this:

byte[] data =…
input.read(data);
You can wrap the InputStream object in an InputStreamReader or BufferedReader to read data at higher level (character and String). For example, using InputStreamReader:

InputStreamReader reader = new InputStreamReader(input);
int character = reader.read();	// reads a single character
And using BufferedReader:

BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line = reader.readLine();	// reads a line of text
 

Close the Connection:

Simply call the close() method on the socket to terminate the connection between the client and the server:

socket.close();
This method also closes the socket’s InputStream and OutputStream, and it can throw IOException if an I/O error occurs when closing the socket.

We recommend you to use the try-with-resource structure so you don’t have to write code to close the socket explicitly.

Now, let’s see some sample programs to learn to code a complete client application. The following examples illustrate how to connect to some well-known Internet services.

 

2. Java Socket Client Example #1: a Daytime Client

The server at time.nist.gov (NIST - National Institute of Standards and Technology) provides a time request service on port 13 (port 13 is for Daytime protocol).

The following program connects to NIST time server to read the current date and time:

import java.net.*;
import java.io.*;

/**
 * This program is a socket client application that connects to a time server
 * to get the current date time.
 *
 * @author www.codejava.net
 */
public class TimeClient {

	public static void main(String[] args) {
		String hostname = "time.nist.gov";
		int port = 13;

		try (Socket socket = new Socket(hostname, port)) {

			InputStream input = socket.getInputStream();
			InputStreamReader reader = new InputStreamReader(input);

			int character;
			StringBuilder data = new StringBuilder();

			while ((character = reader.read()) != -1) {
				data.append((char) character);
			}

			System.out.println(data);


		} catch (UnknownHostException ex) {

			System.out.println("Server not found: " + ex.getMessage());

		} catch (IOException ex) {

			System.out.println("I/O error: " + ex.getMessage());
		}
	}
}
As you can see, this program simply makes a connection and read data from the server. It doesn’t send any data to the server, due to the simple nature of Daytime protocol.

Run this program and you would see the output like this (two blank lines - one after and one before):

58068 17-11-11 10:26:13 00 0 0 152.5 UTC(NIST) *
 This is the current date and time returned by the server, in UTC time zone.

 

3. Java Socket Client Example #2: a Whois Client

Whois is an Internet service that allows you to query information about a specific domain name.

The InterNIC (The Network Information Center) provides a Whois service on port number 43 (port 43 is for Whois protocol).

Hence we can develop the following program to “whois” any domain name we want:

import java.net.*;
import java.io.*;

/**
 * This program demonstrates a client socket application that connects
 * to a Whois server to get information about a domain name.
 * @author www.codejava.net
 */
public class WhoisClient {

	public static void main(String[] args) {
		if (args.length < 1) return;

		String domainName = args[0];

		String hostname = "whois.internic.net";
		int port = 43;

		try (Socket socket = new Socket(hostname, port)) {

			OutputStream output = socket.getOutputStream();
			PrintWriter writer = new PrintWriter(output, true);
			writer.println(domainName);

			InputStream input = socket.getInputStream();

			BufferedReader reader = new BufferedReader(new InputStreamReader(input));

			String line;

			while ((line = reader.readLine()) != null) {
				System.out.println(line);
			}
		} catch (UnknownHostException ex) {

			System.out.println("Server not found: " + ex.getMessage());

		} catch (IOException ex) {

			System.out.println("I/O error: " + ex.getMessage());
		}
	}
}
As you can see, the domain name is passed to the program as an argument. After connected to the server, it sends the domain name, and reads the response from the server.

Run this program from command line using the following command:

java WhoisClient google.com
And you would see some information about the domain google.com like this:

   Domain Name: GOOGLE.COM
   Registry Domain ID: 2138514_DOMAIN_COM-VRSN
   Registrar WHOIS Server: whois.markmonitor.com
   Registrar URL: http://www.markmonitor.com
   Updated Date: 2011-07-20T16:55:31Z
   Creation Date: 1997-09-15T04:00:00Z
   Registry Expiry Date: 2020-09-14T04:00:00Z
   Registrar: MarkMonitor Inc.
   Registrar IANA ID: 292
…
You can see the domain google.com was registered in 1997 and it will expire in 2020.

 

4. Java Socket Client Example #3: a HTTP Client

The following program demonstrates how to connect to a web server via port 80, send a HEAD request and read message sent back from the server:

import java.net.*;
import java.io.*;

/**
 * This program demonstrates a client socket application that connects to
 * a web server and send a HTTP HEAD request.
 *
 * @author www.codejava.net
 */
public class HttpClient {

	public static void main(String[] args) {
		if (args.length < 1) return;

		URL url;

		try {
			url = new URL(args[0]);
		} catch (MalformedURLException ex) {
			ex.printStackTrace();
			return;
		}

		String hostname = url.getHost();
		int port = 80;

		try (Socket socket = new Socket(hostname, port)) {

			OutputStream output = socket.getOutputStream();
			PrintWriter writer = new PrintWriter(output, true);

			writer.println("HEAD " + url.getPath() + " HTTP/1.1");
			writer.println("Host: " + hostname);
			writer.println("User-Agent: Simple Http Client");
			writer.println("Accept: text/html");
			writer.println("Accept-Language: en-US");
			writer.println("Connection: close");
			writer.println();

			InputStream input = socket.getInputStream();

			BufferedReader reader = new BufferedReader(new InputStreamReader(input));

			String line;

			while ((line = reader.readLine()) != null) {
				System.out.println(line);
			}
		} catch (UnknownHostException ex) {

			System.out.println("Server not found: " + ex.getMessage());

		} catch (IOException ex) {

			System.out.println("I/O error: " + ex.getMessage());
		}
	}
}
As you can see, the URL is passed to the program as an argument. The program basically sends a HEAD request (follows HTTP protocol) in the following format:

HEAD <URL> HTTP/1.1
Host: <hostname>
User-Agent: <information about the client>
Accept: <format accepted by the client>
Accept-Language: <language accepted by the client>
Connection: <connection type, close or keep-alive>
Run this program from command line using this command:

java HttpClient http://www.codejava.net/java-core
You would see the server’s response like this:

HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Sat, 11 Nov 2017 10:46:57 GMT
Content-Type: text/html; charset=utf-8
Connection: close
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"
Cache-Control: no-cache
Pragma: no-cache
…
It’s very interesting, isn’t it?

 

5. Java Socket Client Example #4: a SMTP Client

The following program is more interesting, as it demonstrates communication between the program and a SMTP server (We use Google’s mail server - smtp.gmail.com). Here’s the code:

import java.net.*;
import java.io.*;

/**
 * This program demonstrates a socket client program that talks to a SMTP server.
 *
 * @author www.codejava.net
 */
public class SmtpClient {

	public static void main(String[] args) {

		String hostname = "smtp.gmail.com";
		int port = 25;

		try (Socket socket = new Socket(hostname, port)) {

			InputStream input = socket.getInputStream();

			OutputStream output = socket.getOutputStream();
			PrintWriter writer = new PrintWriter(output, true);

			BufferedReader reader = new BufferedReader(new InputStreamReader(input));

			String line = reader.readLine();
			System.out.println(line);

			writer.println("helo " + hostname);

			line = reader.readLine();
			System.out.println(line);

			writer.println("quit");
			line = reader.readLine();
			System.out.println(line);

		} catch (UnknownHostException ex) {

			System.out.println("Server not found: " + ex.getMessage());

		} catch (IOException ex) {

			System.out.println("I/O error: " + ex.getMessage());
		}
	}
}
Basically, this program talks to a server via SMTP protocol, by sending a couple simple SMTP commands like HELO and QUIT. Run this program and you would see the following output:

220 smtp.gmail.com ESMTP w17sm23360916pfa.70 - gsmtp
250 smtp.gmail.com at your service
221 2.0.0 closing connection w17sm23360916pfa.70 - gsmtp
These are the response messages from a SMTP server. The dialogue between the client and the server is actually like this (S for server and C for client):

C: Connect to smtp.gmail.com on port 25
S: 220 smtp.gmail.com ESMTP w17sm23360916pfa.70 - gsmtp
C: helo smtp.gmail.com
S: 250 smtp.gmail.com at your service
C: quit
S: 221 2.0.0 closing connection w17sm23360916pfa.70 - gsmtp
As you can see in the examples above, you can create fully functional Internet applications if you understand the protocol or communication between the client and the server.

 

API Reference:

Socket Class Javadoc

 

Related Java Network Tutorials:

 

Other Java network tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.



Add comment

   


Comments 

#9hello2023-08-18 04:29
hello how are you please sabe me i am under water
Quote
#8Legesse Samuel2022-01-22 08:10
Hi i want that 5 clients messaging with one server java source code on neatbean
Quote
#7purva2021-11-03 07:45
hey can you please tell how can i connect to imap.gmail.com without using javamail
Quote
#6Nam2020-09-12 22:39
Hi Suman,
The code examples in this article is for reading and writing text data - not binary data (PDF in your case).
To read/write binary data, you need to use BufferedInputStream and BufferedOutputStream.
Quote
#5Suman2020-09-11 15:03
Hi I just reused this code to send a PDF file PDF file is getting corrupted and mot being read on the receiving side can someone help !
Quote