FerdouZ Ответов: 4

Может ли многопоточный сервер пересылать данные на сервер(который принимает один клиент)?


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)


Что я уже пробовал:

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

Многопоточный сервер
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);
                    }
                }
    }}
Сервер
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);
    }
}

Richard MacCutchan

Это целая куча кода, но вы не объяснили, в чем заключается проблема и где она возникает.

FerdouZ

Я не могу преобразовать данные многопоточного сервера в сервер, который я получаю от клиентов, и проблема в многопоточной серверной программе.

Richard MacCutchan

Извините, но это нам ни о чем не говорит.

Arthur V. Ratz

Фердуз, вот мое решение ниже.

4 Ответов

Рейтинг:
8

Arthur V. Ratz

Вот ссылка по которой вы можете скачать продукцию основанную на использовании виртуальных машин Oracle Linux 7 которая демонстрирует решение для вашего задания:

JavaCliSrvSockets.zip - Google Диск[^]

И если вы можете скачать его (например, 5,5 ГБ), вы можете увидеть, как работает это решение. :)


FerdouZ

Я устанавливаю это, но я не знаком с этим. Вот почему я не понимаю, что делаю .:(

Arthur V. Ratz

1. Вам необходимо установить oracle virtual box;
2. Скопировать все папки из папок в VirtualBox виртуальных машин с аналогичным папку %имя_пользователя%\папка в VirtualBox виртуальных машин ;

3. Запустить JavaSTServer и JavaMTServer ВМ.

4. запустите JavaClient#1 и JavaClient#2

5. Войдите в систему как root на STServer, MTServer и JavaClient#1, JavaClient#2, используя следующие cridentials: login: "root" password "nullex"

FerdouZ

Спасибо. Теперь я это сделаю.

Рейтинг:
31

Arthur V. Ratz

Кроме того, попробуйте эту версию кода. Это безотказно и может быть полезно.

JavaSTMTServer.zip - Google Диск[^]


FerdouZ

Этот идеально подходит для моего проекта. Большое спасибо.
Возможно ли это преобразовать этот код в swing. Я имею в виду, можем ли мы увидеть этот процесс в SWING GUI?

Arthur V. Ratz

Нет, не сейчас. Извиняюсь.

FerdouZ

Хорошо. Спасибо за помощь, сэр.

Arthur V. Ratz

Я всегда готов помочь любознательному человеку. Однако я не могу помочь вам со Свифтом, потому что никогда с ним не работал. А также мне немного не хватает времени, прямо на данный момент. Но если у вас есть еще какие-то вопросы, просто не стесняйтесь задавать их.

Рейтинг:
20

Arthur V. Ratz

Вот мое решение:

*Редактировать* 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:

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


FerdouZ

Привет Артур,
Когда я запускаю этот проект, он выполняется непрерывно.Могу ли я сделать этот проект похожим на =>
сообщение может быть отправлено от клиента, и он ответит от STserver. Код довольно запутанный, вот почему я не могу понять его правильно.
Спасибо

Arthur V. Ratz

Привет, Фердуз. Я добавил конкретные комментарии к коду, чтобы вы могли понять его правильно. Кроме того, я дал объяснение основной идеи этого решения. Пожалуйста, прочтите и оставьте свой комментарий, если вы можете понять решение прямо сейчас.

FerdouZ

Привет, Артур, Спасибо за добавление комментария в код. на самом деле я хочу именно так
"Однако правильное протокольное решение заключается в том, что каждый клиент отправляет сообщение запроса на многопоточный сервер, который немедленно пересылает входящие запросы на однопоточный сервер, который, в свою очередь, отправляет дату ответа обратно на многопоточный сервер, а затем пересылает его обратно конкретному клиенту. Это правильное и наиболее подходящее решение этой проблемы."
Могу ли я отправить сообщение/данные вручную от клиентов, и он автоматически ответит с сервера?
Спасибо

Arthur V. Ratz

- Да, можешь. Я использовал таймер только для демонстрационных целей. Нужен модифицированный код ? Я переработаю код клиентского приложения и опубликую его в качестве решения.

Arthur V. Ratz

Фердуз, теперь вы можете использовать код для отправки сообщений запроса без таймера, так что вы можете отправлять сообщения/данные вручную от клиентов, и он будет автоматически отвечать с сервера...

FerdouZ

Большое спасибо, Артур, за помощь.
На самом деле, к сожалению, он автоматически завершается после отправки одного значения. могу ли я сделать это способным отправлять несколько значений от клиентов, и это будет прекращено после отправки "выхода" или любого конкретного значения?
Спасибо.

Arthur V. Ratz

Отправка нескольких значений от каждого клиента по ТИКам таймера уже была реализована. Если вы хотите изменить поведение этого приложения с помощью своего собственного, пожалуйста, скажите мне, что должно делать ваше клиентское приложение, и я постараюсь вам помочь.

FerdouZ

Клиентское приложение может отправлять данные вручную несколько раз,и оно будет прекращено после отправки одного конкретного значения, такого как Exit, Over и т. д..
Пример:один клиент отправляет одни данные, а затем автоматически получает ответ от сервера.тогда один и тот же клиент может снова отправлять разные данные и так далее ... тогда клиент может прервать соединение, когда захочет.

Arthur V. Ratz

Означает ли это на самом деле, что клиентское приложение должно получать пользовательский ввод ? Если да, то я скоро опубликую обновление.

FerdouZ

да, это нужно для получения пользовательского ввода, но мне нужно принимать ввод несколько раз от одного и того же клиента.
Спасибо

FerdouZ

Еще одна вещь, сэр, здесь STserver принимает несколько соединений, но я хочу только одно соединение.

Arthur V. Ratz

STserver в этом случае поддерживает только одно соединение с MTServer

Arthur V. Ratz

Пожалуйста, наконец, дайте мне знать, были ли все эти вещи, которые я разместил в качестве решения, полезны или нет.

Arthur V. Ratz

Это только для моего интереса. :)

Arthur V. Ratz

Просто для вашего интереса, на эту тему стоит написать статью. Я имею в виду вопросы, связанные с Java-сокетами.

FerdouZ

Благодарю вас, сэр, это прекрасно работает.Теперь я понимаю.
Еще раз спасибо за помощь . :)

Arthur V. Ratz

Всегда пожалуйста, сэр.

Arthur V. Ratz

Вот ваше решение, получающее пользовательский ввод, опубликованное выше.

FerdouZ

Если STserver отключен на некоторое время, то запустите его снова, после чего можно получить автоматическое соединение с MTserver, с которым сервер соединялся ранее.Если возможно,можете помочь мне, как это сделать, сэр?

Arthur V. Ratz

- Нет проблем, сэр. Я помогу тебе выбраться. Я опубликую свой улучшенный код чуть позже. В настоящее время я работаю над этим.

FerdouZ

Окей сэр, благодарю вас.

Arthur V. Ratz

Фердуз, я опубликовал свое обновление решения в качестве решения 2 для вашего вопроса. Скачайте файл по ссылке ниже и скажите мне, работает ли он для вас или нет.

Arthur V. Ratz

Фердуз, у меня есть готовое решение. Можете ли вы пересмотреть решение ?

FerdouZ

Извините, сэр, за поздний ответ. Эта ссылка не работает.можете ли вы проверить?

Рейтинг:
20

Arthur V. Ratz

Привет, Фердуз. Вот мое решение, о котором вы меня только что просили:

JavaMTSTServerLib.zip - Google Диск[^]

Попробуйте этот вариант с последними обновлениями кода и вернитесь, чтобы обсудить его.


FerdouZ

Извините, сэр, за поздний ответ. Эта ссылка не работает. Можете проверить?

Arthur V. Ratz

Фердуз, сори за мой запоздалый ответ. Это была проблема с файлообменником. Теперь я обновил ссылку на архив, так что вы можете смело скачивать и использовать его. Мне интересно, работает ли для вас следующий код. Просто оставьте свой комментарий ниже после того, как вы протестировали код.

FerdouZ

Привет, Артур, я скачал код .Это хорошо работает. Спасибо за помощь. :)

Arthur V. Ratz

Тебе еще нужна моя помощь ? Если да, то разместите свое сообщение здесь.