несколько серверов, которые также являются клиентами - общение в JAVA - PullRequest
1 голос
/ 04 апреля 2019

Я использую сокеты в JAVA, и у меня есть 3 Сервера, которые являются Клиентами одновременно. Я хочу, чтобы они обменялись информацией.

Вот что я хочу создать: Three peer machines

Ввод должен быть примерно таким:

Сервер запущен по адресу: /172.16.2.22: 8080 информация для первого, информация для второго, информация для третьего,

Сервер запущен по адресу: /172.16.2.22: 8081 информация для первого, информация для второго, информация для третьего,

Сервер запущен по адресу: /172.16.2.22: 8082 информация для первого, информация для второго, информация для третьего,

Но по какой-то причине он показывает только информацию о клиенте, который в данный момент также является сервером.

Итак, я получаю такой результат:

Сервер запущен по адресу: /172.16.2.22: 8080 информация для первого

Сервер запущен по адресу: /172.16.2.22: 8081 информация для второго

Сервер запущен по адресу: /172.16.2.22: 8082 информация для третьего

Вот как я запускаю свой код, Сервер :

    private void startServer() {

    ServerSocket providerSocket = null;
    BufferedReader in = null;
    try {
        InetAddress addr = InetAddress.getByName(this.serv.getIP());
        providerSocket = new ServerSocket(this.serv.getPort(), 50, addr);
        System.out.println("ServThread started at:" + addr + ":" + this.serv.getPort());


        // create a new thread object
        Thread t = new ClientHandler(providerSocket);

        // Invoking the start() method
        t.start();


    } catch (IOException e) {
        e.printStackTrace();
    }

    }

Это ClientHandler , который я использую для потоков :

    class ClientHandler extends Thread {

    final ServerSocket s;

    // Constructor
    public ClientHandler(ServerSocket s) {
        this.s = s;
    }

    public void run() {

        Socket s = null;
        try {
            s = this.s.accept();
        } catch (IOException e) {
            e.printStackTrace();
        }
        while (true) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {

                BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
                // receive the answer from client


                String line = null;
                while ((line = in.readLine()) != null) {
                    System.out.println(line);
                }


            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}

И, наконец, мои Клиенты , которые также являются серверами. Я использую цикл for для чтения текста со всех IP-адресов, портов моих серверов:

    private void startSender() {

    for (MyServers servs : ServersTXT.fetchTXTofServers()) {
        BufferedWriter out;
        try (Socket s = new Socket(servs .getIP(), servs .getPort())) {
            out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            out.write(servs.info());
            out.newLine();
            out.flush();
        } catch (ConnectException err) {
            // Connection failed because not all servers on the txt are up
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}

1 Ответ

0 голосов
/ 06 апреля 2019

Мне потребовалось некоторое время, чтобы понять вашу архитектуру, и мне удалось выяснить, в чем была проблема.ClientHandler действительно неверен, потому что часть connection.accept () находится вне цикла while, и соединения теряются.Архитектура, которую вы пытаетесь достичь, имеет следующее правило.Как только я получаю соединение, создаю поток для обработки этого соединения не только один раз, но и непрерывно.Приведенный выше код решит вашу проблему, если вы поместите его в функцию запуска в потоке ClientHandler .

ServerSocket providerSocket;
Socket connection;
InetAddress addr;
try {
    addr = InetAddress.getByName(this.broker.getIP());
    providerSocket = new ServerSocket(this.broker.getPort(), 50, addr);
    while (true) {
        connection = providerSocket.accept();
        ObjectOutputStream out = new ObjectOutputStream(connection.getOutputStream());
        ObjectInputStream in = new ObjectInputStream(connection.getInputStream());
        System.out.println(n.readUTF());
        in.close();
        out.close();
        connection.close();
    }
} catch (Exception err) {
      err.printStackTrace();
}

Также в отправителечасть, в блоке try вы пытаетесь выполнить код в скобках, обычно блоки try не содержат скобок, в моем коде я удалил его.

...