Serving A Client by Creating A New Thread Using TCP/UDP Socket

Download as pdf or txt
Download as pdf or txt
You are on page 1of 9

Serving a client by creating a new thread using

TCP/UDP socket.
We don’t want only a single client to connect to server at a particular time but many
clients simultaneously. We want our architecture to support multiple clients at the same
time. For this reason, we must use threads on server side so that whenever a client
request comes, a separate thread can be assigned for handling each request.

As normal, we will create two java files,Server.java and Client.java. Server file contains
two classes namely Server (public class for creating server) and ClientHandler (for
handling any client using multithreading). Client file contain only one public class Client
(for creating a client).

Server class :

● Establishing the Connection: Server socket object is initialized and


inside a while loop a socket object continuously accepts incoming
connection.
● Obtaining the Streams: The inputstream object and outputstream object
is extracted from the current requests’ socket object.
● Creating a handler object: After obtaining the streams and port number, a
new clientHandler object (the above class) is created with these
parameters.
● Invoking the start() method : The start() method is invoked on this newly
created thread object.

// Java implementation of Server side


// It contains two classes : Server and ClientHandler
// Save file as Server.java
import java.io.*;
import java.text.*;
import java.util.*;
import java.net.*;

// Server class
public class Server
{
public static void main(String[] args) throws IOException
{
// server is listening on port 5056
ServerSocket ss = new ServerSocket(5056);
// running infinite loop for getting
// client request
while (true)
{
Socket s = null;
try
{
// socket object to receive incoming client requests
s = ss.accept();
System.out.println("A new client is connected : " +
s);
// obtaining input and out streams
DataInputStream dis = new
DataInputStream(s.getInputStream());
DataOutputStream dos = new
DataOutputStream(s.getOutputStream());
System.out.println("Assigning new thread for this
client");
// create a new thread object
Thread t = new ClientHandler(s, dis, dos);
// Invoking the start() method
t.start();

}
catch (Exception e){
s.close();
e.printStackTrace();
}
}
}
}
// ClientHandler class
class ClientHandler extends Thread
{
DateFormat fordate = new SimpleDateFormat("yyyy/MM/dd");
DateFormat fortime = new SimpleDateFormat("hh:mm:ss");
final DataInputStream dis;
final DataOutputStream dos;
final Socket s;
// Constructor
public ClientHandler(Socket s, DataInputStream dis,
DataOutputStream dos)
{
this.s = s;
this.dis = dis;
this.dos = dos;
}
@Override
public void run()
{
String received;
String toreturn;
while (true)
{
try {
// Ask user what he wants
dos.writeUTF("What do you want?[Date | Time]..\n"+
"Type Exit to terminate connection.");
// receive the answer from client
received = dis.readUTF();
if(received.equals("Exit"))
{
System.out.println("Client " + this.s + " sends
exit...");
System.out.println("Closing this connection.");
this.s.close();
System.out.println("Connection closed");
break;
}
// creating Date object
Date date = new Date();
// write on output stream based on the
// answer from the client
switch (received) {
case "Date" :
toreturn = fordate.format(date);
dos.writeUTF(toreturn);
break;
case "Time" :
toreturn = fortime.format(date);
dos.writeUTF(toreturn);
break;
default:
dos.writeUTF("Invalid input");
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
try
{
// closing resources
this.dis.close();
this.dos.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
Output
A new client is connected :
Socket[addr=/127.0.0.1,port=60536,localport=5056]
Assigning new thread for this client
Client Socket[addr=/127.0.0.1,port=60536,localport=5056] sends
exit...
Closing this connection.
Connection closed

ClientHandler class :

● First of all this class extends Thread so that its objects assumes all
properties of Threads.
● Secondly, the constructor of this class takes three parameters, which can
uniquely identify any incoming request, i.e. a Socket, a DataInputStream
to read from and a DataOutputStream to write to. Whenever we receive
any request of client, the server extracts its port number, the
DataInputStream object and DataOutputStream object and creates a new
thread object of this class and invokes start() method on it.
Note : Every request will always have a triplet of socket, input stream and
output stream. This ensures that each object of this class writes on one
specific stream rather than on multiple streams.
● Inside the run() method of this class, it performs three operations: request
the user to specify whether time or date needed, read the answer from
input stream object and accordingly write the output on the output stream
object.
// Java implementation for a client

// Save file as Client.java

import java.io.*;

import java.net.*;

import java.util.Scanner;

// Client class

public class Client {

public static void main(String[] args) throws IOException {

try {

Scanner scn = new Scanner(System.in);

// getting localhost ip

InetAddress ip = InetAddress.getByName("localhost");

// establish the connection with server port 5056

Socket s = new Socket(ip, 5056);

// obtaining input and out streams

DataInputStream dis = new


DataInputStream(s.getInputStream());

DataOutputStream dos = new


DataOutputStream(s.getOutputStream());

// the following loop performs the exchange of

// information between client and client handler

while (true) {

System.out.println(dis.readUTF());

String tosend = scn.nextLine();


dos.writeUTF(tosend);

// If client sends exit,close this connection

// and then break from the while loop

if (tosend.equals("Exit")) {

System.out.println("Closing this connection : " +


s);

s.close();

System.out.println("Connection closed");

break;

// printing date or time as requested by client

String received = dis.readUTF();

System.out.println(received);

// closing resources

scn.close();

dis.close();

dos.close();

} catch (Exception e) {

e.printStackTrace();

}
Output :
What do you want?[Date | Time]..
Type Exit to terminate connection.
Date
2017/06/16
What do you want?[Date | Time]..
Type Exit to terminate connection.
Time
05:35:28
What do you want?[Date | Time]..
Type Exit to terminate connection.
Geeks
Invalid input
What do you want?[Date | Time]..
Type Exit to terminate connection.
Exit
Closing this connection :
Socket[addr=localhost/127.0.0.1,port=5056,localport=60536]
Connection closed

Working Process:

1. When a client, say client1 sends a request to connect to server, the


server assigns a new thread to handle this request. The newly assigned
thread is given the access to streams for communicating with the client.
2. After assigning the new thread, the server via its while loop, again
comes into accepting state.
3. When a second request comes while first is still in process, the server
accepts this requests and again assigns a new thread for processing it.
In this way, multiple requests can be handled even when some requests
are in process.

You might also like