Click here to Skip to main content
15,887,928 members
Please Sign up or sign in to vote.
2.28/5 (4 votes)
See more:
I am trying to forward data from multithreaded server to single clients server.
The process like=> 
Clients >>> Multithread Server >>>> server (which accept only one client)


What I have tried:

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

public class Client
{
    // initialize socket and input output streams
    private Socket sockett            = null;
    private DataInputStream  inputt   = null;
    private DataOutputStream outt     = null;
    private DataInputStream  Innn   = null;
 
    // constructor to put ip address and port
    @SuppressWarnings("deprecation")
	public Client(String address, int port)throws IOException 
    {
        // establish a connection
        try
        {
            sockett = new Socket(address, port);
            System.out.println("Connected");
 
            // takes input from terminal
            inputt  = new DataInputStream(System.in);
 
            // sends output to the socket
            outt    = new DataOutputStream(sockett.getOutputStream());
            Innn=new DataInputStream(
                    new BufferedInputStream(sockett.getInputStream()));
        }
        catch(UnknownHostException u)
        {
            System.out.println(u);
        }
        catch(IOException i)
        {
            System.out.println(i);
        }
 
        // string to read message from input
        String line = "";
 
        // keep reading until "Over" is input
        while (!line.equals("Over"))
        {
            try
            {
                line = inputt.readLine();
                outt.writeUTF(line);
                line = Innn.readUTF();
                System.out.println(line);
            }
            catch(IOException i)
            {
                System.out.println(i);
            }
        }
 
        // close the connection
        try
        {
            inputt.close();
            outt.close();
            sockett.close();
            Innn.close();
        }
        catch(IOException i)
        {
            System.out.println(i);
        }
    }

    public static void main(String args[]) throws IOException
    {
        @SuppressWarnings("unused")
		Client client = new Client("127.0.0.1", 5056);
    }
}

Multi thread server
public class server 
{     
    public static void main(String[] args) throws IOException 
    {
        // server is listening on port 5056
        @SuppressWarnings("resource")
		ServerSocket ss = new ServerSocket(5056);
         
        // running infinite loop for getting
        // client request
        while (true) 
        {
            Socket s = null;
            Socket    socket= null;
            Socket    socket1= null;
            DataInputStream inn=  null;
            DataOutputStream outt=  null;
            DataInputStream in =null;
            DataOutputStream out=null;
            try
            {
                // socket object to receive incoming client requests
                socket = ss.accept();
                 
                System.out.println("A new client is connected : " + s);
                 
                // obtaining input and out streams
                in = new DataInputStream(
                        new BufferedInputStream(socket.getInputStream())); 
                socket1 = new Socket("127.0.01", 5001);
                System.out.println("Connected");
                out = new DataOutputStream(socket1.getOutputStream());
                inn = new DataInputStream(
                        new BufferedInputStream(socket1.getInputStream())); 
                outt = new DataOutputStream(socket.getOutputStream()); 
                System.out.println("Assigning new thread for this client");
 
                // create a new thread object
                Thread t = new ClientHandler(in,inn,outt,out);
 
                // Invoking the start() method
                t.start();
                 
            }
            catch (Exception e){
                socket.close();
                e.printStackTrace();
            }
        }
    }
}
 
// ClientHandler class
class ClientHandler extends Thread 
{
    
   DataInputStream in       =  null;
   DataInputStream inn      =  null;
   DataOutputStream out      =  null;
   DataOutputStream outt      =  null; 
 
    // Constructor
    public ClientHandler(DataInputStream in, DataInputStream inn, DataOutputStream out, DataOutputStream outt) 
    {
        this.in = in;
        this.inn = inn;
        this.out = out;
        this.outt= outt;
    }
    @Override
    public void run() 
    {
        String line="";
        while (true) 
        {
            try {
 
            	while (!line.equals("Over"))
                    {
                        line = in.readUTF();
                        System.out.println(line);
                     
                        out.writeUTF(line);
                        line = inn.readUTF();
                        System.out.println(line);
                        outt.writeUTF(line);
                        
                    }}
                    catch(IOException i)
                    {
                        System.out.println(i);
                    }
                }
    }}
Server
import java.net.*;
import java.io.*;

public class Serever2
{
    //initialize socket and input stream
    private Socket          socket1   = null;
    private ServerSocket    server2   = null;
    private DataInputStream in1      =  null;
    private DataInputStream input      =  null;
    private DataOutputStream out1 = null;
 
    // constructor with port
    public Serever2(int port)throws IOException 
    {
        // starts server and waits for a connection
        try
        {
            server2 = new ServerSocket(port);
            System.out.println("Server started");
 
            System.out.println("Waiting for a client ...");
 
            socket1 = server2.accept();
            System.out.println("Client accepted");
 
            // takes input from the client socket
            in1 = new DataInputStream(
                new BufferedInputStream(socket1.getInputStream()));
            input  = new DataInputStream(System.in);
            out1    = new DataOutputStream(socket1.getOutputStream());
            String line = "";
            
            // reads message from client until "Over" is sent
            while (!line.equals("Over"))
            {
                try
                {
                    line = in1.readUTF();
                    System.out.println(line);
                    
                    out1.writeUTF("Thank you");
                }
                catch(IOException i)
                {
                    System.out.println(i);
                }
            }
            System.out.println("Closing connection");
 
            // close connection
            socket1.close();
            in1.close();
            input.close();
            out1.close();
        }
        catch(IOException i)
        {
            System.out.println(i);
        }
    }
 
    public static void main(String args[]) throws IOException
    {
        @SuppressWarnings("unused")
		Serever2 server = new Serever2(5001);
    }
}
Posted
Updated 14-Aug-18 21:13pm
Comments
Richard MacCutchan 6-Aug-18 3:14am    
That is a whole lot of code, but you have not explained what the problem is or where it occurs.
FerdouZ 6-Aug-18 5:27am    
I am not able to convert the data multithread server to server which I get from clients and the problem in Multi thread server program.
Richard MacCutchan 6-Aug-18 8:49am    
Sorry, but that does not tell us anything.
Arthur V. Ratz 6-Aug-18 11:28am    
FerdouZ, here's my solution below.

Also, try this version of code. It's fail-safe and might be useful as well.

JavaSTMTServer.zip - Google Drive[^]
 
Share this answer
 
Comments
FerdouZ 15-Aug-18 3:48am    
This one is perfect for my project. Thank you very much.
Is this possible to convert this code in swing. I mean can we see the process in SWING GUI?
Arthur V. Ratz 15-Aug-18 4:08am    
No not at this time. Sorry.
FerdouZ 15-Aug-18 4:18am    
Okey. Thank you for helping sir.
Arthur V. Ratz 15-Aug-18 4:38am    
I'm always ready to help an inquirer. However I can not help you with swift, because I never worked with it. And also I'm a bit short of time right at the current moment. But if you have any other questions, just don't hesitate to ask them.
Here's my solution:

*EDIT* ClientApp.java:

Java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package clientapp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Arthur V. Ratz
 */
public class ClientApp {
    
    // Declare an asynchronous thread class
    public static class QueueClientThread extends Thread {
        private BufferedReader m_in;
        // Pass the buffered reader object to the constructor
        public QueueClientThread(BufferedReader in) {
            m_in = in;
        }
        public void run() {
            // Run into an endless eternal loop to enforce receiving messages
            // from the multi-threaded server in real-time mode
            while (true) {
                try {
                    String msg_buf = "\0";
                    // Fetch each incoming response data received from multi-
                    // threaded server, forwarded back from single-threaded
                    // server at the back-end
                    while ((msg_buf = m_in.readLine()) != null) {
                        // Print out the response message received
                        System.out.println("Greetings from singlethreaded server: " + msg_buf);
                    }
                // Assert on the IO exception
                } catch (IOException ex) {
                    // Log the specific IO exception
                    Logger.getLogger(ClientApp.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // Set multithreaded server hostname
        String hostName = "127.0.0.1";
        // Set multithreaded server port number
        int portNumber = Integer.parseInt("5056");
        
        try {
        
            // Instantinate client's socket object    
            Socket clientSocket = new Socket(hostName, portNumber);
            // Instantinate print writer object to send requests to
            // multi-threaded server
            PrintWriter outputStream = new PrintWriter(
                    clientSocket.getOutputStream(), true);
            
            TimerTask clientTask;
            // Create a timer task object 
            clientTask = new TimerTask() {
                // Implement run() method that will send a message
                // to multi-threaded server via a client socket created
                public void run() {
                    // Print out message
                    System.out.println("Sending a message...");
                    // Send a message with randomly generated msg_id to
                    // multi-threaded server
                    outputStream.println("msg_id: " + Integer.toString(
                            new Random().nextInt(1000) + 1));
                    try {

                        // Launch the asynchronous thread to receive the
                        // responses from multithreaded server, forwarded by
                        // single-threaded server at the back-end
                        new QueueClientThread(new BufferedReader(
                            new InputStreamReader(clientSocket.getInputStream()))).start();
                      // Assert on the IO exception
                    } catch (IOException ex) {
                        // Log the error
                        Logger.getLogger(ClientApp.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            };
            
            // Execute a timer-task each 1000 ms to send out a message to
            // multi-threaded server.
            new Timer().schedule(clientTask, 200L, 1000L);
        // Assert on the IO exception
        } catch (IOException ex) {
            // Log the IO exception if socket opened fails
            Logger.getLogger(ClientApp.class.getName()).log(Level.SEVERE, null, ex);
        }
     }
}



*EDIT* MTServer.java:

Java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package mtserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Arthur V. Ratz
 */
public class MTServer {

    // Declaring the asynchronous thread class
    public static class QueueClientThread extends Thread {
        private BufferedReader m_in;
        private PrintWriter m_out;
        // Passing the buffered reader and print writer objects to the constructor
        public QueueClientThread(BufferedReader in, PrintWriter out) {
            m_in = in; m_out = out;
        }
        public void run() {
            // Enter an endless eternal while-loop to enforce multithreaded-
            // server incoming socket to receive incoming data from single-threaded
            // server in real-time mode.
            while (true) {
                try {
                    String msg_buf = "\0";
                    // Retrieving messages from each client by calling
                    // buffered reader's readLine(…) method
                    while ((msg_buf = m_in.readLine()) != null) {
                        // For each message redirect it back to specific client, from
                        // which a client socket was accepted and connection 
                        // established
                        System.out.println("Message sent back to client: " + msg_buf);
                        m_out.println("Message sent back to client: " + msg_buf);
                    }
                // Assert on IO exception
                } catch (IOException ex) {
                    // Log the error
                    Logger.getLogger(MTServer.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }    
    
    // Declaring the asynchronous thread class
    public static class QueueMTServerThread extends Thread {
        private Socket m_Socket;
        // Passing the client socket object the constructor
        public QueueMTServerThread(Socket socket) {
            m_Socket = socket;
        }
        public void run() {
            try (
                // Instantinate printer writer object to send data to single threaded
                // server
                PrintWriter out =
                    new PrintWriter(m_Socket.getOutputStream(), true);                   
               
                // Instantinate the buffered reader to fetch the requests data
                // sent to multithreaded server by one or more clients
                BufferedReader in = new BufferedReader(
                    new InputStreamReader(m_Socket.getInputStream()));
            ) {
                String inputLine;
                // Fetching data sent by each client by calling buffered reader's 
                // readLine(…) method and forward the data to single threaded server
                while ((inputLine = in.readLine()) != null) {
                    System.out.println(inputLine);
                    //out.println(inputLine);
                    
                    // Setting the hostname of single-threaded server
                    String hostName = "127.0.0.1";
                    // Setting the port number of the single-threaded server
                    int portNumber = Integer.parseInt("5058");
            
                    // Creating a client socket object to establish connection
                    // to single-threaded server
                    Socket clientSocket = new Socket(hostName, portNumber);

                    // Instantinating the printer writer object to send
                    // data to single-threaded server
                    PrintWriter outputStream = new PrintWriter(
                            clientSocket.getOutputStream(), true);

                    // Forward current incoming message to single-threaded server
                    outputStream.println(inputLine);
                    
                    // Launch the asynchronous thread to receive data back
                    // from single-threaded server
                    new QueueClientThread(new BufferedReader(
                      new InputStreamReader(clientSocket.getInputStream())), out).start();
                }
            // Assert on the IO exception
            } catch (IOException e) {
                // Print out exception message
                System.out.println(e.getMessage());
            }            
        }   
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        // Assign the tcp protocol port number
        int portNumber = Integer.parseInt("5056");
        try {
            // Instantinate server socket object to listen tcp port 5056
            ServerSocket serverSocket = new ServerSocket(
                    Integer.parseInt("5056"));     

            // Entering the endless eternal while-loop during the execution
            // of which we accept a client socket for each client's connection
            // making it possible to accept and data sent by one or more clients at 
            // once. After that we're running asynchronous thread providing the
            // basic functionality for receiving and managing incoming requests from
            // multiple clients.
            while (true) {
                Socket clientSocket = serverSocket.accept();
                // Launch the asynchronous socket thread
                new QueueMTServerThread(clientSocket).start();
            }
            
        // Assert on the IO exception
        } catch (IOException ex) {
            // Log the error occurred
            Logger.getLogger(MTServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}



*EDIT* STServer.java:


Java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package stserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Arthur V. Ratz
 */
public class STServer {
    
        // Declaring the asynchronous thread class
        public static class QueueClientThread extends Thread {
        private BufferedReader m_in;
        private PrintWriter m_out;
        // Passing buffered reader and print writer objects to the constructor
        public QueueClientThread(BufferedReader in, PrintWriter out) {
            m_in = in; m_out = out;
        }
        public void run() {
            // Entering the endless eternal loop to make sure that the asynchronous
            // threads is proceeding to receive incoming messages in real-time mode
            while (true) {
                try {
                    String msg_buf = "\0";
                    // Fetching data from socket by invoking buffered reader's
                    // readLine(…) method. If the socket receives any data,
                    // the request contents are modified and sent back to client
                    // (e.g. to multithreaded server)
                    while ((msg_buf = m_in.readLine()) != null) {
                        // Printing diagnostic message
                        System.out.println("Response from singlethreaded server: " + msg_buf);
                        // Sending out the modified data back to client
                        m_out.println("Response from singlethreaded server: " + msg_buf);
                    }
                // Catch the IO socket exception
                } catch (IOException ex) {
                    // Log the exception
                    Logger.getLogger(STServer.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }    
    
   /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        // Assign the tcp protocol port number
        int portNumber = Integer.parseInt("5058");
             
        // Instantinate server socket object to listen tcp port 5058
        ServerSocket serverSocket = new ServerSocket(Integer.parseInt("5058"));     
        // Entering endless eternal loop to enforce the single threaded server
        // receive incoming messages forwarded from clients by the multithreaded 
        // server and respond each incoming message back to multithreaded server
        while (true) {
            try {
                    // Getting client socket object
                    Socket clientSocket = serverSocket.accept();
                    // Instantinate print writer to send data back to clients by     
                    // using output stream 
                    PrintWriter out =
                       new PrintWriter(clientSocket.getOutputStream(), true);                 

                    // Instantinate buffer reader to accept and read incoming data  
                    BufferedReader in = new BufferedReader(
                        new InputStreamReader(clientSocket.getInputStream()));

                    // Run the asynchronous thread to receive incoming requests
                    new QueueClientThread(new BufferedReader(
                        new InputStreamReader(clientSocket.getInputStream())), out).start();
            
                // Catch IO exception in case if socket operations fail
                } catch (IOException ex) {
                    Logger.getLogger(STServer.class.getName()).log(Level.SEVERE, null, ex);
                }       
        }
    }
}


Link to the Oracle's NetBeans Java ready-to-use project:

MTSTServerSocks.zip[^]

P.S. My solution might at the very first look be rather confusing. I've not left any comments to the fragments of code posted. So, if you've got any questions about this stuff please don't hesitate to give your questions under this topic discussion forum. I'm ready to help you out to understand how to create servers based on various sockets of either multi-client or single-client.


That's all folks. Enjoy.


Arthur.


Quote:
Can I make this project like =>
a message can send from client and it will reply from STserver.


If I've used to know that you need exactly to send response messages from single-threaded server to clients directly, I would have provided this solution much earlier :). However, the proper protocol solution is that each client sends a request message to multithreaded server that immediately forwards the incoming requests to single threaded server, that, in turn, sending response date back to multithreaded server and then it forwarding it back to a specific client. That's the proper and most appropriate solution of this problem.


Now, just in a few words about the code. Normally, this entire code implements a single-threaded server that is much similar to an echo server discussed in Reading from and Writing to a Socket (The Java™ Tutorials > Custom Networking > All About Sockets)[^] - Oracle's tutorial for Java sockets and inter-networking. The single-threaded server (e.g. STServer.java) does nothing but receiving incoming messages from socket currently opened and sending response data back to its client. Unlike the multithreaded server it basically accepts only one client per connection being established.

In turn, the multithreaded server accepts multiple incoming clients connections being established. For each of this connection and request being received it typically establishes a single client socket connection to the single-threaded server and feeds the specific request data to it. The single-threaded server receives the request data sent and responses immediately to the multi-threaded server with response data, which is received by multithreaded server's client socket and is redirected to the client's socket accepted by multithreaded server.

A client Java application is mainly based on creating a client socket that will connect to the multithreaded server right after the client app fires a timer event, to send a request message to multithreaded server. Also, the client app implements the functionality for receiving responses from multithreaded server by launching an asynchronous thread, while executing which, the response messages are fetched from the client socket opened.


Let's recall that single- and multithreaded servers, as well as the client app implement almost the same socket functionality for sending and receiving data via the client or server socket being opened. The following code illustrates a socket used to send and receive data from a server for which a connection is established:

Java
public class ClientApp {
    
    public static class QueueClientThread extends Thread {
        private BufferedReader m_in;
        public QueueClientThread(BufferedReader in) {
            m_in = in;
        }
        public void run() {
            while (true) {
                try {
                    String msg_buf = "\0";
                    while ((msg_buf = m_in.readLine()) != null) {
                         // Process an incoming message
                    }
                } catch (IOException ex) {
                    Logger.getLogger(ClientApp.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        String hostName = "127.0.0.1";
        int portNumber = Integer.parseInt("5056");
        
        try {
            
            Socket clientSocket = new Socket(hostName, portNumber);
            PrintWriter outputStream = new PrintWriter(
                    clientSocket.getOutputStream(), true);

            // Sending data to server via opened client socket            
            outputStream.println(some_data);
            try {
                   // Launch an asynchronous thread to receive response
                   // data from server
                   new QueueClientThread(new BufferedReader(
                      new InputStreamReader(clientSocket.getInputStream()))).start();
                    } catch (IOException ex) {
                       Logger.getLogger(ClientApp.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            };
            
        } catch (IOException ex) {
            Logger.getLogger(ClientApp.class.getName()).log(Level.SEVERE, null, ex);
        }
     }
}



You can use the same concept for implementing the either client's or server's socket functionality.


That's all. Here's my explanation of your problem solution discussed above.


If you've got any questions or comments, just post your message in this topic's forum.

Arthur.


Here's client app's code modification that uses socket and sends a single request message without timer:


Java
/**
 *
 * @author Arthur V. Ratz
 */
public class ClientApp {
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // Setting server hostname 127.0.0.1
        String hostName = "127.0.0.1";
        // Setting server port number 5056
        int portNumber = Integer.parseInt("5056");
        
        try {
            
            // Create client socket to communicate with server
            Socket clientSocket = new Socket(hostName, portNumber);
            // Instantinate the print writer object to send out data
            PrintWriter outputStream = new PrintWriter(
                    clientSocket.getOutputStream(), true);
            
            // Instantinate the buffer reader object to fetch
            // multithreaded server response data
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(clientSocket.getInputStream()));
            
            // Print out `Sending a message...` string
            System.out.println("Sending a message...");
            // Send request message to server
            outputStream.println("msg_id: " + Integer.toString(
                 new Random().nextInt(1000) + 1));

            // Get the response message from server
            String msg_buf = in.readLine();
            // Print the response data received from server
            System.out.println("Greetings from singlethreaded server: " + msg_buf);
            
            // Close the connection and socket
            outputStream.close(); in.close(); clientSocket.close();

        // Assert on the IO exception
        } catch (IOException ex) {
            // Log the error
            Logger.getLogger(ClientApp.class.getName()).log(Level.SEVERE, null, ex);
        }
     }
}



Enjoy. :).


There's also one improvement and one important tip making the solution even more efficient:


1. To provide a high reliability of multithreaded server let's add messages queueing functionality as follows:

Java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package mtserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Arthur V. Ratz
 */
public class MTServer {

    public static class QueueClientThread extends Thread {
        private BufferedReader m_in;
        private PrintWriter m_out;
        // Declare an array list of messages to be queued
        private ArrayList<String> m_MsgsQueue = new ArrayList<String>();
        public QueueClientThread(BufferedReader in, PrintWriter out) {
            m_in = in; m_out = out;
        }
        public void run() {
            while (true) {
                try {
                    String msg_buf = "\0";
                    while ((msg_buf = m_in.readLine()) != null) {
                        System.out.println("Message sent back to client: " + msg_buf);
                        
                        // Enqueue current response message arrived from a client
                        m_MsgsQueue.add(msg_buf);

                        // Dispatch all response messages to their clients
                        for (int index = 0; index < m_MsgsQueue.size(); index++) {
                            // Send the current message in the queue to its client
                            m_out.println("Message sent back to client: " + m_MsgsQueue.get(index));
                        }
                    }
                } catch (IOException ex) {
                    Logger.getLogger(MTServer.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }    
    
    public static class QueueMTServerThread extends Thread {
        private Socket m_Socket;
        private ArrayList<String> m_MsgsQueue = new ArrayList<String>();
        public QueueMTServerThread(Socket socket) {
            m_Socket = socket;
        }
        public void run() {
            try (
                PrintWriter out =
                    new PrintWriter(m_Socket.getOutputStream(), true);                   
                BufferedReader in = new BufferedReader(
                    new InputStreamReader(m_Socket.getInputStream()));
            ) {
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    System.out.println(inputLine);
                    //out.println(inputLine);
        
                    // Enqueue the current message from client
                    m_MsgsQueue.add(inputLine);
                    
                    String hostName = "127.0.0.1";
                    int portNumber = Integer.parseInt("5058");
            
                    Socket clientSocket = new Socket(hostName, portNumber);
                    PrintWriter outputStream = new PrintWriter(
                            clientSocket.getOutputStream(), true);

                    // Dispatch all incoming messages to singlethreaded server
                    for (int index = 0; index < m_MsgsQueue.size(); index++) {
                         // Send the current message in the queue to its client
                         outputStream.println(m_MsgsQueue.get(index));
                    }
                    
                    new QueueClientThread(new BufferedReader(
                      new InputStreamReader(clientSocket.getInputStream())), out).start();
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }            
        }   
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        int portNumber = Integer.parseInt("5056");
        try {
            ServerSocket serverSocket = new ServerSocket(
                    Integer.parseInt("5056"));     

            while (true) {
                Socket clientSocket = serverSocket.accept();
                new QueueMTServerThread(clientSocket).start();
            }
            
        } catch (IOException ex) {
            Logger.getLogger(MTServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}



2. To make sure that the solution will work for you when you'll be using it on real servers and not to use virtual machines at the same time, make sure that you will assign different localhost ip addresses (i.e. hostnames). To do this just edit your Windows\System32\drivers\etc\hosts.txt file as follows:


# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#	127.0.0.1       localhost
#	::1             localhost

127.0.0.1 localhost
127.0.0.2 localhost
127.0.0.3 localhost



After this assign 127.0.0.2:5056 to multithreaded server,
127.0.0.3:5058 for singlethreaded server.


If the solution is working for you after that, then it means that java sockets were used correctly. :)


Here's client app update that receives user input:

ClientApp.java:

Java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package clientapp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Arthur V. Ratz
 */
public class ClientApp {
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // Setting server hostname 127.0.0.1
        String hostName = "127.0.0.1";
        // Setting server port number 5056
        int portNumber = Integer.parseInt("5056");
        
        try {
            
            // Create client socket to communicate with server
            Socket clientSocket = new Socket(hostName, portNumber);
            // Instantinate the print writer object to send out data
            PrintWriter outputStream = new PrintWriter(
                    clientSocket.getOutputStream(), true);
            
            // Instantinate the buffer reader object to fetch
            // multithreaded server response data
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(clientSocket.getInputStream()));
            
            // Instantinate the buffer reader object to read data from stdin
            BufferedReader stdIn =
                new BufferedReader(new InputStreamReader(System.in));

            Boolean done = false;
            while (done == false) {
            
                System.out.print("Type in your message /> ");
            
                // Retrieve each line from user input
                String userInput = stdIn.readLine();
                  
                if (userInput.equals("Quit") || userInput.equals("Exit")) {
                    done = true; break;
                }
                    
                // Print out `Sending a message...` string
                System.out.println("Sending a message...");
                // Send current request message to server
                outputStream.println(userInput);
                
                String msg_buf =  in.readLine();
                System.out.println("Greetings from singlethreaded server: " + msg_buf);
            }

            // Close the connection and socket
            outputStream.close(); in.close(); clientSocket.close();

        // Assert on the IO exception
        } catch (IOException ex) {
            // Log the error
            Logger.getLogger(ClientApp.class.getName()).log(Level.SEVERE, null, ex);
        }
     }
}



MTServer.java:


Java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package mtserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Arthur V. Ratz
 */
public class MTServer {

    public static class QueueClientThread extends Thread {
        private BufferedReader m_in;
        private PrintWriter m_out;
        public QueueClientThread(BufferedReader in, PrintWriter out) {
            m_in = in; m_out = out;
        }
        public void run() {
            while (true) {
                try {
                    String msg_buf = "\0";
                    while ((msg_buf = m_in.readLine()) != null) {
                        System.out.println("Message sent back to client: " + msg_buf);
                        m_out.println("Message sent back to client: " + msg_buf);
                    }
                } catch (IOException ex) {
                    Logger.getLogger(MTServer.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }    
    
    public static class QueueMTServerThread extends Thread {
        private Socket m_Socket;
        public QueueMTServerThread(Socket socket) {
            m_Socket = socket;
        }
        public void run() {
            try (
                PrintWriter out =
                    new PrintWriter(m_Socket.getOutputStream(), true);                   
                BufferedReader in = new BufferedReader(
                    new InputStreamReader(m_Socket.getInputStream()));
            ) {
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    System.out.println(inputLine);
                    
                    String hostName = "127.0.0.1";
                    int portNumber = Integer.parseInt("5058");
            
                    Socket clientSocket = new Socket(hostName, portNumber);
                    PrintWriter outputStream = new PrintWriter(
                            clientSocket.getOutputStream(), true);

                    outputStream.println(inputLine);
                    
                    new QueueClientThread(new BufferedReader(
                      new InputStreamReader(clientSocket.getInputStream())), out).start();
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }            
        }   
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        int portNumber = Integer.parseInt("5056");
        try {
            ServerSocket serverSocket = new ServerSocket(
                    Integer.parseInt("5056"));     

            while (true) {
                Socket clientSocket = serverSocket.accept();
                new QueueMTServerThread(clientSocket).start();
            }
            
        } catch (IOException ex) {
            Logger.getLogger(MTServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
 
Share this answer
 
v6
Comments
FerdouZ 6-Aug-18 18:34pm    
Hello Arthur,
When I run this project it's execute continuously.Can I make this project like =>
a message can send from client and it will reply from STserver. The code is quite confusing that's why i can't understand properly.
Thank you
Arthur V. Ratz 6-Aug-18 20:37pm    
Hello FerdouZ. I've added specific comments to the code so you can understand it properly. Also, I've provided the explanation of basic idea for this solution. Please, read and leave your comment if you can understand the solution now.
FerdouZ 6-Aug-18 23:36pm    
Hello Arthur, Thanks for adding comment in the code. actually I want exactly like
"However, the proper protocol solution is that each client sends a request message to multithreaded server that immediately forwards the incoming requests to single threaded server, that, in turn, sending response date back to multithreaded server and then it forwarding it back to a specific client. That's the proper and most appropriate solution of this problem."
Can I able to send message/data manually from clients and it will reply automatically from server?
Thank you
Arthur V. Ratz 6-Aug-18 23:41pm    
Yes you can. I've used timer for demonstration purposes only. Need a modified code ? I will rework client app's code and post it as the solution.
Arthur V. Ratz 7-Aug-18 0:02am    
FerdouZ, now you can use the code for sending request messages without timer so you're able to send message/data manually from clients and it will reply automatically from server...
Hello, FerdouZ. Here's my solution as just you've been asking me for:

JavaMTSTServerLib.zip - Google Drive[^]

Try this one with latest code updates and come back to discuss.
 
Share this answer
 
v2
Comments
FerdouZ 13-Aug-18 13:34pm    
Sorry sir for late reply. This link is not working. Can you check?
Arthur V. Ratz 14-Aug-18 0:26am    
FerdouZ, sory for my late reply. It was a file hosting problem. Now, I've updated the link to archive, so you can feel free to download and use it. It's interesting to me if the following code works for you. Just post your comment below after you've tested the code.
FerdouZ 15-Aug-18 2:43am    
Hi Arthur, I downloaded the code .It's working well. Thanks for helping. :)
Arthur V. Ratz 15-Aug-18 3:09am    
Do you need my help any more ? If so, post your message here.
Here's the link by using which you can download the production based on using Oracle Linux 7 VMs that demonstrates the solution for your assignment:

JavaCliSrvSockets.zip - Google Drive[^]

And if you can download it (e.g. 5.5GB) you can see how this solution works. :)
 
Share this answer
 
Comments
FerdouZ 15-Aug-18 2:45am    
I install this but I am not familiar with this. That's why I am not understand what do .:(
Arthur V. Ratz 15-Aug-18 3:09am    
1. You need to install oracle virtual box;
2. Copy all folders from VirtualBox VMs folder to the similar folder under %USER_PROFILE%\VirtualBox VMs folder;

3. Run JavaSTServer and JavaMTServer VMs.

4. Run JavaClient#1 and JavaClient#2

5. Login as root on STServer, MTServer and JavaClient#1, JavaClient#2 using the following cridentials: login: "root" password "nullex"
FerdouZ 15-Aug-18 3:31am    
Thank you. Now I will do it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900