简体   繁体   English

如何使用套接字将多个服务器连接到Java客户端?

[英]How to connect multiple servers to a client in Java using Sockets?

I'm doing a program by sockets, from a single client to multiple servers, on the internet I have not found information about this 我正在通过套接字执行程序,从单个客户端到多个服务器,在互联网上我还没有找到关于此的信息

The system consists of connecting multiple servers to a single client, the client must request a number from a user, then, in the server, with that number an algorithm will be executed that will find the number of prime numbers between 0 and N , afterwards, the execution time of the algorithm is calculated, and then sent to the client. 系统包括将多个服务器连接到单个客户端,客户端必须从用户请求一个号码,然后在服务器中使用该号码执行一个算法,该算法将找到0到N之间的素数个数,之后,计算算法的执行时间,然后发送给客户端。 Each time of each server is sent to the client and the client stores them. 每个服务器的每次发送到客户端,客户端存储它们。

The problem is that this connection must be simultaneous between the number of servers to be desired, in addition to this connection being synchronized. 问题是除了正在同步的连接之外,此连接必须在所需的服务器数量之间同时进行。

For the moment, I have made a simple code, from a client to a server. 目前,我已经制作了一个简单的代码,从客户端到服务器。

MAIN SERVER 主服务器

public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Server s = new Server(5000, "Hilo servidor");
    s.start();
    }

}

MODULE SERVER 模块服务器

This is a method that is inside the server class, this class executes the algorithm to count how many cousins there are and to send that time to the client. 这是一个位于服务器类内部的方法,该类执行算法来计算有多少堂兄弟,并将该时间发送给客户端。 It runs when calling c.start () in the main server 它在主服务器中调用c.start()时运行

private void startServer() {

            try {
                ServerSocket ss = new ServerSocket(port);
                System.out.println("Esperando Conexion");
                Socket socket = ss.accept();


                DataInputStream in = new DataInputStream(socket.getInputStream());
                int n = in.readInt();
                long time = encontrarPrimeros(n);
                DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                out.writeLong(time);
                System.out.println(time);
            } catch (IOException ex) {
                Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
            }
}

MAIN CLIENT 主要客户

public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
            Client c = new Client("Hilo cliente", 5000, "192.168.0.19");
            c.start();
    }

}

MODULE CLIENT 模块客户端

    private void startClient() {
            try {
                    Socket socket = new Socket(ip, port); 
                    DataOutputStream out = new DataOutputStream(socket.getOutputStream());


                    System.out.println("Ingrese dato...");
                    Scanner scanner = new Scanner(System.in);
                    int n = scanner.nextInt();
                    out.writeInt(n);
                    DataInputStream in = new DataInputStream(socket.getInputStream());
                    long tiempo = in.readLong();
                    System.out.println(tiempo);
                    socket.close();
            } catch (IOException ex) {
                    Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
            }
    }

The problem is, how can I connect several servers to a client, so they start synchronized? 问题是,如何将多个服务器连接到客户端,以便它们开始同步?

Thank you 谢谢

Update 更新

I have modified the client's main method, because of this: 我修改了客户端的main方法,因为:

public class Main {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    Client c = new Client("Hilo cliente", 5000, "192.168.0.19");
    Client c2 = new Client("Hilo cliente", 5000, "192.168.0.19");
    c.start();
    c2.start();
}

} }

But when executing, I get the following error: 但是在执行时,我收到以下错误:

mar 23, 2019 7:14:10 PM Client startClient
GRAVE: null
java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:210)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at java.io.DataInputStream.readFully(DataInputStream.java:195)
    at java.io.DataInputStream.readLong(DataInputStream.java:416)
    at Client.startClient(Client.java:69)
    at Client.run(Client.java:41)
    at java.lang.Thread.run(Thread.java:748)

The instruction where the error is executed is the following: long tiempo = in.readLong(); 执行错误的指令如下: long tiempo = in.readLong();

Actually, in socket programming: 实际上,在套接字编程中:

  • a client can only connect to one server 客户端只能连接到一台服务器
  • a server can receive many client connections 服务器可以接收许多客户端连接
  • The client manages his connection to the server through a socket object 客户端通过套接字对象管理与服务器的连接

If your client needs to connect to many servers, the client must create as many socket objects as the number of servers. 如果客户端需要连接到许多服务器,则客户端必须创建与服务器数量一样多的套接字对象。 And in order to manage the communication in parallel, you can create a separate thread on which you manage the IO for each socket. 并且为了并行管理通信,您可以创建一个单独的线程来管理每个套接字的IO。

So applied to your scenario: 因此适用于您的场景:

  • you can keep your Client class as it manages one socket 您可以在管理一个套接字时保留Client类
  • you create N objects of the Client in the number of servers (you associate each Client instance with only one server) 在服务器数量中创建客户端的N个对象(将每个客户端实例与一个服务器关联)
  • you can make your Client class runnable (by inheriting from Thread class). 您可以使您的Client类可运行(通过继承Thread类)。
  • you run your Client as a thread (you can place the startClient() class in the protected void run() method that you inherit from Thread). 您将客户端作为线程运行(您可以将startClient()类放在从Thread继承的protected void run()方法中)。
  • In your main you call each client object start() method (inherited from thread). 在您的主体中,您调用每个客户端对象的start()方法(继承自线程)。 this will run the run() method in background. 这将在后台运行run()方法。
  • to collect all the results, you call join() on each Client object 要收集所有结果,请在每个Client对象上调用join()

Client Class Example 客户端类示例

    public class Client extends Thread {

    private String ip;
    private int port;


    public Client(String serverIP, int serverPort) {
        this.ip = new String(serverIP);
        this.port = serverPort;
    }

    private void startClient() {
        try {
            Socket socket = new Socket(ip, port); 
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());

            System.out.println("Ingrese dato...");
            Scanner scanner = new Scanner(System.in);
            int n = scanner.nextInt();
            out.writeInt(n);
            DataInputStream in = new DataInputStream(socket.getInputStream());
            long tiempo = in.readLong();
            System.out.println(tiempo);
            socket.close();
        } catch (IOException ex) {
            ex.getStackTrace();
        }
    }

    @Override
    public void run() {

        startClient();

        super.run();
    }
}

Main 主要

Client client1 = new Client("192.168.1.100", 8888);
    Client client2 = new Client("192.168.1.101", 8888);
    Client client3 = new Client("192.168.1.102", 8888);

    client1.start();
    client2.start();
    client3.start();

    try {
        client1.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    try {
        client2.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    try {
        client3.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

Server Class 服务器类

public class Server extends Thread {


ExecutorService threadPool = Executors.newCachedThreadPool();

//Private class
class ClientSocket implements Runnable {

    private Socket m_socket;

    ClientSocket(Socket sock) {
        m_socket = sock;
    }

    @Override
    public void run() {
        try {
            DataInputStream in = new DataInputStream(m_socket.getInputStream());
            int n = in.readInt();
            long time = n;
            DataOutputStream out = new DataOutputStream(m_socket.getOutputStream());
            out.writeLong(time);
            out.flush();
            System.out.println(time);
            System.out.flush();
        } catch (IOException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}


@Override
public void run() {
    startServer();
    super.run();
}

private void startServer() {

    try {
        ServerSocket ss = new ServerSocket(8888);
        System.out.println("Esperando Conexion");

        do {
            Socket socket = ss.accept();

            threadPool.execute(new ClientSocket(socket));

        } while(true);

    } catch (IOException ex) {
        Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
    }
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM