0% found this document useful (0 votes)
9 views13 pages

Java Socket Server Examples (TCP - IP)

The document outlines the steps to create a multi-threaded server socket in Java, detailing how to bind a server socket to a port, accept client connections, read and send data, and close connections. It provides examples of a simple time server and a reverse server, demonstrating both single-threaded and multi-threaded implementations. The document emphasizes the importance of handling each client connection in a separate thread to allow the server to manage multiple clients simultaneously.

Uploaded by

Anima
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views13 pages

Java Socket Server Examples (TCP - IP)

The document outlines the steps to create a multi-threaded server socket in Java, detailing how to bind a server socket to a port, accept client connections, read and send data, and close connections. It provides examples of a simple time server and a reverse server, demonstrating both single-threaded and multi-threaded implementations. The document emphasizes the importance of handling each client connection in a separate thread to allow the server to manage multiple clients simultaneously.

Uploaded by

Anima
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

1.

Create a server socket and bind it to a specific port number

2. Listen for a connection from the client and accept it. This results in a client
socket is created for the connection.

3. Read data from the client via an InputStream obtained from the client
socket.

4. Send data to the client via the client socket’s OutputStream.

5. Close the connection with the client.

The steps 3 and 4 can be repeated many times depending on the protocol agreed
between the server and the client.

The steps 1 to 5 can be repeated for each new client. And each new connection
should be handled by a separate thread.

Let’s dive into each step in details.

Create a Server Socket:


Create a new object of the ServerSocket class by using one of the following
constructors:

- ServerSocket(int port): creates a server socket that is bound to the


specified port number. The maximum number of queued incoming
connections is set to 50 (when the queue is full, new connections are
refused).

- ServerSocket(int port, int backlog): creates a server socket that is


bound to the specified port number and with the maximum number of queued
connections is specified by the backlog parameter.

- ServerSocket(int port, int backlog, InetAddress bindAddr):


creates a server socket and binds it to the specified port number and a local
IP address.
PRICE DROP PRICE DROP PRICE DROP

So when to use which?

Use the first constructor for a small number of queued connections (less than 50) and
any local IP address available.

Use the second constructor if you want to explicitly specify the maximum number of
queued requests.

And use the third constructor if you want to explicitly specify a local IP address to be
bound (in case the computer has multiple IP addresses).

And of course, the first constructor is preferred for simple usage. For example, the
following line of code creates a server socket and binds it to the port number 6868:

1 ServerSocket serverSocket = new ServerSocket(6868);

Note that these constructors can throw IOException if an I/O error occurs when
opening the socket, so you have to catch or re-throw it.

Listen for a connection:


Once a ServerSocket instance is created, call accept() to start listening for
incoming client requests:

1 Socket socket = serverSocket.accept();

Note that the accept() method blocks the current thread until a connection is made.
And the connection is represented by the returned Socket object.

Read data from the client:


Once a Socket object is returned, you can use its InputStream to read data sent
from the client like this:

1 InputStream input = socket.getInputStream();

The InputStream allows you to read data at low level: read to a byte array. So if you
want to read the data at higher level, wrap it in an InputStreamReader to read data
as characters:

1 InputStreamReader reader = new InputStreamReader(input);


2 int character = reader.read(); // reads a single character

You can also wrap the InputStream in a BufferedReader to read data as String,
for more convenient:

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


2 String line = reader.readLine(); // reads a line of text

Send data to the client:


Use the OutputStream associated with the Socket to send data to the client, for
example:

1 OutputStream output = socket.getOutputStream();

As the OutputStream provides only low-level methods (writing data as a byte array),
you can wrap it in a PrintWriter to send data in text format, for example:

1 PrintWriter writer = new PrintWriter(output, true);


2 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).

Close the client connection:


Invoke the close() method on the client Socket to terminate the connection with
the client:

1 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.

Of course the server is still running, for serving other clients.

Terminate the server:


A server should be always running, waiting for incoming requests from clients. In case
the server must be stopped for some reasons, call the close() method on the
ServerSocket instance:
1 serverSocket.close();

When the server is stopped, all currently connected clients will be disconnected.

The ServerSocket class also provides other methods which you can consult in its
Javadoc here.

Implement a multi-threaded server:


So basically, the workflow of a server program is something like this:

1 ServerSocket serverSocket = new ServerSocket(port);


2
3 while (true) {
4 Socket socket = serverSocket.accept();
5
6 // read data from the client
7 // send data to the client
8 }

The while(true) loop is used to allow the server to run forever, always waiting for
connections from clients. However, there’s a problem: Once the first client is
connected, the server may not be able to handle subsequent clients if it is busily
serving the first client.

Therefore, to solve this problem, threads are used: each client socket is handled by a
new thread. The server’s main thread is only responsible for listening and accepting
new connections. Hence the workflow is updated to implement a multi-threaded
server like this:

1 while (true) {
2 Socket socket = serverSocket.accept();
3
4 // create a new thread to handle client socket
5 }

You will understand clearly in the examples below.


2. Java Server Socket Example #1: Time Server
The following program demonstrates how to implement a simple server that returns
the current date time for every new client. Here’s the code:

1 import java.io.*;
2 import java.net.*;
3 import java.util.Date;
4
5 /**
6 * This program demonstrates a simple TCP/IP socket server.
7 *
8 * @author www.codejava.net
9 */
10 public class TimeServer {
11
12 public static void main(String[] args) {
13 if (args.length < 1) return;
14
15 int port = Integer.parseInt(args[0]);
16
17 try (ServerSocket serverSocket = new ServerSocket(port)) {
18
19 System.out.println("Server is listening on port " + port);
20
21 while (true) {
22 Socket socket = serverSocket.accept();
23
24 System.out.println("New client connected");
25
26 OutputStream output = socket.getOutputStream();
27 PrintWriter writer = new PrintWriter(output, true);
28
29 writer.println(new Date().toString());
30 }
31
32 } catch (IOException ex) {
33 System.out.println("Server exception: " + ex.getMessage());
34 ex.printStackTrace();
35 }
36 }
37 }

You need to specify a port number when running this server program, for example:
1 java TimeServer 6868

This makes the server listens for client requests on the port number 6868. You would
see the server’s output:

1 Server is listening on port 6868

And the following code is for a client program that simply connects to the server and
prints the data received, and then terminates:
1 import java.net.*;
2 import java.io.*;
3
4 /**
5 * This program demonstrates a simple TCP/IP socket client.
6 *
7 * @author www.codejava.net
8 */
9 public class TimeClient {
10
11 public static void main(String[] args) {
12 if (args.length < 2) return;
13
14 String hostname = args[0];
15 int port = Integer.parseInt(args[1]);
16
17 try (Socket socket = new Socket(hostname, port)) {
18
19 InputStream input = socket.getInputStream();
20 BufferedReader reader = new BufferedReader(new InputStreamR
21
22 String time = reader.readLine();
23
24 System.out.println(time);
25
26
27 } catch (UnknownHostException ex) {
28
29 System.out.println("Server not found: " + ex.getMessage());
30
31 } catch (IOException ex) {
32
33 System.out.println("I/O error: " + ex.getMessage());
34 }
35 }
36 }

To run this client program, you have to specify the hostname/IP address and port
number of the server. If the client is on the same computer with the server, type the
following command to run it:

1 java TimeClient localhost 6868

Then you see a new output in the server program indicating that the client is
connected:
1 New client connected

And you should see the client’s output:

1 Mon Nov 13 11:00:31 ICT 2017

This is the date time information returned from the server. Then the client terminates
and the server is still running, waiting for new connections. It’s that simple.

3. Java Socket Server Example #2: Reverse Server


(single-threaded)
Next, let’s see a more complex socket server example. The following server program
echoes anything sent from the client in reversed form (hence the name
ReverseServer). Here’s the code:

1 import java.io.*;
2 import java.net.*;
3
4 /**
5 * This program demonstrates a simple TCP/IP socket server that echoes
6 * message from the client in reversed form.
7 * This server is single-threaded.
8 *
9 * @author www.codejava.net
10 */
11 public class ReverseServer {
12
13 public static void main(String[] args) {
14 if (args.length < 1) return;
15
16 int port = Integer.parseInt(args[0]);
17
18 try (ServerSocket serverSocket = new ServerSocket(port)) {
19
20 System.out.println("Server is listening on port " + port);
21
22 while (true) {
23 Socket socket = serverSocket.accept();
24 System.out.println("New client connected");
25
26 InputStream input = socket.getInputStream();
27 BufferedReader reader = new BufferedReader(new InputStr
27 BufferedReader reader = new BufferedReader(new InputStr
28
29 OutputStream output = socket.getOutputStream();
30 PrintWriter writer = new PrintWriter(output, true);
31
32
33 String text;
34
35 do {
36 text = reader.readLine();
37 String reverseText = new StringBuilder(text).revers
38 writer.println("Server: " + reverseText);
39
40 } while (!text.equals("bye"));
41
42 socket.close();
43 }
44
45 } catch (IOException ex) {
46 System.out.println("Server exception: " + ex.getMessage());
47 ex.printStackTrace();
48 }
49 }
50 }

As you can see, the server continues serving the client until it says ‘bye’. Run this
server program using the following command:

1 java ReverseServer 9090

The server is up and running, waiting for incoming requests from clients:

1 Server is listening on port 9090

Now, let’s create a client program. The following program connects to the server,
reads input from the user and prints the response from the server. Here’s the code:

1 import java.net.*;
2 import java.io.*;
3
4 /**
5 * This program demonstrates a simple TCP/IP socket client that reads i
6 * from the user and prints echoed message from the server.
7 *
8 * @author www codejava net
8 * @author www.codejava.net
9 */
10 public class ReverseClient {
11
12 public static void main(String[] args) {
13 if (args.length < 2) return;
14
15 String hostname = args[0];
16 int port = Integer.parseInt(args[1]);
17
18 try (Socket socket = new Socket(hostname, port)) {
19
20 OutputStream output = socket.getOutputStream();
21 PrintWriter writer = new PrintWriter(output, true);
22
23 Console console = System.console();
24 String text;
25
26 do {
27 text = console.readLine("Enter text: ");
28
29 writer.println(text);
30
31 InputStream input = socket.getInputStream();
32 BufferedReader reader = new BufferedReader(new InputStr
33
34 String time = reader.readLine();
35
36 System.out.println(time);
37
38 } while (!text.equals("bye"));
39
40 socket.close();
41
42 } catch (UnknownHostException ex) {
43
44 System.out.println("Server not found: " + ex.getMessage());
45
46 } catch (IOException ex) {
47
48 System.out.println("I/O error: " + ex.getMessage());
49 }
50 }
51 }

As you can see, this client program is running until the user types ‘bye’. Run it using
the following command:
1 java ReverseClient localhost 9090

Then it asks you to enter some text:

1 Enter text:_

Type something, say ‘Hello’ and you should see the server’s response like this:

1 Enter text: Hello


2 Server: olleH
3 Enter text:_

You see the server responds ‘Server: olleH’ in which ‘olledH’ is the reversed form of
‘Hello’. The text ‘Server:’ is added to clearly separate client’s message and server’s
message. The client program is still running, asking input and printing server’s
response until you type ‘bye’ to terminate it.

Keep this first client program running, and start a new one. In the second client
program, you will see it asks for input and then hangs forever. Why?

It’s because the server is single-threaded, and while it is busily serving the first client,
subsequent clients are block.

Let’s see how to solve this problem in the next example.

4. Java Socket Server Example #3: Reverse Server


(multi-threaded)
Modify the server’s code to handle each socket client in a new thread like this:
1 import java.io.*;
2 import java.net.*;
3
4 /**
5 * This program demonstrates a simple TCP/IP socket server that echoes
6 * message from the client in reversed form.
7 * This server is multi-threaded.
8 *
9 * @author www.codejava.net
10 */
11 public class ReverseServer {
12
13 public static void main(String[] args) {
14 if (args.length < 1) return;
15
16 int port = Integer.parseInt(args[0]);
17
18 try (ServerSocket serverSocket = new ServerSocket(port)) {
19
20 System.out.println("Server is listening on port " + port);
21
22 while (true) {
23 Socket socket = serverSocket.accept();
24 System.out.println("New client connected");
25
26 new ServerThread(socket).start();
27 }
28
29 } catch (IOException ex) {
30 System.out.println("Server exception: " + ex.getMessage());
31 ex.printStackTrace();
32 }
33 }
34 }

You see, the server creates a new ServerThread for every socket client:

1 while (true) {
2 Socket socket = serverSocket.accept();
3 System.out.println("New client connected");
4
5 new ServerThread(socket).start();
6 }

The ServerThread class is implemented as follows:

You might also like