Почему мой соединитель не получает сообщение хоста? - PullRequest
0 голосов
/ 23 апреля 2019

Резюме

Я делаю простую одноранговую шахматную игру на Java.Хост успешно соединяется, но соединитель не получает свое сообщение.Я использую PrintWriter и BufferedReader для отправки и получения сообщений.Я подозреваю, что PrintWriter ведет себя неправильно, но я не уверен.

Предыдущее исследование

Я искал "Клиент не получает сообщение сервера", но проблема, с которой сталкивались все, не использовала println со своими PrintWriter.Я использую println, поэтому ни один из них не применяется ко мне.Я также переместил поля ввода и вывода из метода в класс, что, как сказал один из ответов, но это не решило проблему.

Некоторый код

Код прослушивания

try (ServerSocket serverSocket = new ServerSocket(this.port)) {
    // We need to connect with another computer
    if (this.other == null || this.other.isClosed()) {
        System.out.println("Looking for connection on port " + serverSocket.getLocalPort());
        this.in = null;
        this.out = null;
        // Listen for connectors
        this.other = serverSocket.accept();
        // Someone tried to connect, handle connection
        System.out.println("Player connected");
        this.in = new BufferedReader(new InputStreamReader(this.other.getInputStream()));
        this.out = new PrintWriter(this.other.getOutputStream(), true);
        // Autoflush is enabled!                                 ^^^^
        // This does not get to the client
        this.sendMessage("connectHost");
    }
    // We are currently connected to another computer, no need to look for more
    else {
        String input = this.in.readLine();
        System.out.println("Received '" + input + "'");

        if (input != null) {
            // Handle input
        }
    }
} catch (IOException ioe) {
    ioe.printStackTrace();
}

Отправка кода

if (this.out != null) {
    // See, it is println, so I don't need to call out.flush()...
    this.out.println(message);
    System.out.println("Sent '" + message + "'");
}

Код команды подключения

try {
    // The host picks up on this
    this.other = new Socket(ip, port);
    this.in = new BufferedReader(new InputStreamReader(this.other.getInputStream()));
    this.out = new PrintWriter(this.other.getOutputStream(), true);
    // Works
    this.sendMessage("test");
} catch (IOException ioe) {
    ioe.printStackTrace();
}

Неисправность

На разъеме должно быть напечатано Received 'connectHost', но этоне бываетВместо этого он блокируется из вызываемого in.readLine() без получения in данных.Если я вставлю in.ready() чек, он всегда вернет false.

Консоль коннектора

Looking for connection on port 57479
connect localhost 57478 // Command to connect to host
Sent 'test' // Successfully goes to the host
// Now it blocks. This is intended, but it should be saying "Received 'connectHost'" beforehand.

Хост-консоль

Looking for connection on port 57478
Player connected
Sent 'connectHost'
Received 'test' // Host gets it
// This also blocks, waiting for more messages, but that is intended.

Обновление: я только что попробовалотправка сообщения сразу после подключения (см. обновленный код) и хост получает его.Разъем все еще не получает тот от хоста.

1 Ответ

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

Это было очевидно ...

serverSocket.accept() блокировал, не позволяя разъему читать вход. Так что in.readLine() не было проблемой. Я сделал это так, что пользователь должен сказать программе прослушивать соединения. Теперь это работает.

Новый код

Код прослушивания

try (ServerSocket serverSocket = new ServerSocket(this.port)) {
    if (this.listening && (this.other == null || this.other.isClosed())) {
        System.out.println("Looking for connection on port " + serverSocket.getLocalPort());
        this.in = null;
        this.out = null;
        this.other = serverSocket.accept();
        this.in = new BufferedReader(new InputStreamReader(this.other.getInputStream()));
        this.out = new PrintWriter(this.other.getOutputStream(), true);
    } else if (this.in != null) {System.out.println("Looking for input");
        String input = this.in.readLine();
        System.out.println("Received '" + input + "'");

        if (input != null) {
            // Process input
        }
    }
} catch (IOException ioe) {
    ioe.printStackTrace();
}

Код отправки не изменился.

Код подключения

if (input.contains("connect")) {
    String[] args = input.replaceAll("connect ", "").split(" ");
    String ip = args[0];
    int port = Integer.parseInt(args[1]);

    try {
        this.other = new Socket(ip, port);
        this.in = new BufferedReader(new InputStreamReader(this.other.getInputStream()));
        this.out = new PrintWriter(this.other.getOutputStream(), true);
        this.sendMessage("connect");
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
} else if (input.contains("listen")) {
    this.listening = true;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...