多线程服务器可以将数据转发到服务器(接受单个客户端)吗? [英] Can multithreaded server forward data to server(which accept single client)?

查看:77
本文介绍了多线程服务器可以将数据转发到服务器(接受单个客户端)吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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);
    }
}

推荐答案

此外,请尝试此版本的代码。它是故障安全的,也可能有用。



JavaSTMTServer .zip - Google云端硬盘 [ ^ ]
Also, try this version of code. It's fail-safe and might be useful as well.

JavaSTMTServer.zip - Google Drive[^]


这是我的解决方案:



*编辑* ClientApp.java:



Here's my solution:

*EDIT* ClientApp.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);
        }
     }
}







*编辑* MTServer.java:






*EDIT* MTServer.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);
        }
    }
}







*编辑* STServer.java:








*EDIT* STServer.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.







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.

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:





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:

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:








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:


/**
 *
 * @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:






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:

/*
 * 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:








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:






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:

/*
 * 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:








MTServer.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);
        }
    }
}


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


这篇关于多线程服务器可以将数据转发到服务器(接受单个客户端)吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆