簡體   English   中英

如何使用套接字將多個服務器連接到Java客戶端?

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

我正在通過套接字執行程序,從單個客戶端到多個服務器,在互聯網上我還沒有找到關於此的信息

系統包括將多個服務器連接到單個客戶端,客戶端必須從用戶請求一個號碼,然后在服務器中使用該號碼執行一個算法,該算法將找到0到N之間的素數個數,之后,計算算法的執行時間,然后發送給客戶端。 每個服務器的每次發送到客戶端,客戶端存儲它們。

問題是除了正在同步的連接之外,此連接必須在所需的服務器數量之間同時進行。

目前,我已經制作了一個簡單的代碼,從客戶端到服務器。

主服務器

public class Main {

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

}

模塊服務器

這是一個位於服務器類內部的方法,該類執行算法來計算有多少堂兄弟,並將該時間發送給客戶端。 它在主服務器中調用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);
            }
}

主要客戶

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

}

模塊客戶端

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

問題是,如何將多個服務器連接到客戶端,以便它們開始同步?

謝謝

更新

我修改了客戶端的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();
}

}

但是在執行時,我收到以下錯誤:

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)

執行錯誤的指令如下: long tiempo = in.readLong();

實際上,在套接字編程中:

  • 客戶端只能連接到一台服務器
  • 服務器可以接收許多客戶端連接
  • 客戶端通過套接字對象管理與服務器的連接

如果客戶端需要連接到許多服務器,則客戶端必須創建與服務器數量一樣多的套接字對象。 並且為了並行管理通信,您可以創建一個單獨的線程來管理每個套接字的IO。

因此適用於您的場景:

  • 您可以在管理一個套接字時保留Client類
  • 在服務器數量中創建客戶端的N個對象(將每個客戶端實例與一個服務器關聯)
  • 您可以使您的Client類可運行(通過繼承Thread類)。
  • 您將客戶端作為線程運行(您可以將startClient()類放在從Thread繼承的protected void run()方法中)。
  • 在您的主體中,您調用每個客戶端對象的start()方法(繼承自線程)。 這將在后台運行run()方法。
  • 要收集所有結果,請在每個Client對象上調用join()

客戶端類示例

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

主要

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

服務器類

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