Java Socket Server Examples (TCP - IP)
Java Socket Server Examples (TCP - IP)
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.
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.
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:
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.
Note that the accept() method blocks the current thread until a connection is made.
And the connection is represented by the returned Socket object.
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:
You can also wrap the InputStream in a BufferedReader to read data as String,
for more convenient:
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:
The argument true indicates that the writer flushes the data after each method call
(auto flush).
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.
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.
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 }
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:
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:
Then you see a new output in the server program indicating that the client is
connected:
1 New client connected
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.
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:
The server is up and running, waiting for incoming requests from clients:
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
1 Enter text:_
Type something, say ‘Hello’ and you should see the server’s response like this:
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.
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 }