Java: сокет закрыть соединение и ObjectInputStream - PullRequest
0 голосов
/ 12 октября 2009

Мой код выглядит следующим образом, это код сервера (Runnable)

public void run() {
    while (true) {
        try {
            System.out.println("Waiting for client...");
            this.socket = serverSocket.accept();
            System.out.println("Client accepted");
            while (true) {
                readCommand();
                try {
                    Thread.sleep(2);
                } catch (Exception e) {
                }
            }
        } catch (Exception ex) {
            Main.error("Server stopped for current host", ex);
        }
    }
}

Моя проблема: когда клиент закрывает соединение, он все еще ожидает чтения команды в readCommand(); до тех пор, пока команда не будет отправлена ​​и не будет выдано EOFException. Это мой readCommand метод:

private void readCommand() throws Exception {
    Object o = new ObjectInputStream(socket.getInputStream()).readObject();
    if (o instanceof Command) {
        ((Command) o).execute();
        return;
    }
    if (o instanceof Recorder) {
        System.out.println("Recording received");
        ((Recorder) o).executeRecord();
        return;
    }
    if (o instanceof MyKeyEvent) {
        ((MyKeyEvent) o).execute();
        return;
    }
}

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

Редактировать: Если я оцениваю код run -метода, EOFException добавляется в try-catch-body. Но он перестает принимать клиентов.

Ответы [ 2 ]

3 голосов
/ 12 октября 2009

EOFException - это именно то, что я ожидал бы, если бы клиент закрыл соединение. Так что я не совсем уверен, что ваша проблема на самом деле является . Возможно, вам необходимо различать ожидаемое отключение клиента и неожиданное отключение клиента. В таком случае, возможно, вам следует отправить какой-то объект End-of-message, чтобы отметить окончание передачи?

Если вы хотите проверить, доступна ли информация, в потоке есть метод available () . Я не думаю, что вам нужен ваш Thread.sleep(2), кстати, так как я ожидал бы, что чтение в допустимом входном потоке зависнет при отсутствии данных.

0 голосов
/ 12 октября 2009

Вы также можете просто добавить еще одну попытку, чтобы поймать только EOFException

public void run() {
    while (true) {
        try {
            System.out.println("Waiting for client...");
            this.socket = serverSocket.accept();
            System.out.println("Client accepted");
            try {
                while (true) {
                    readCommand();
                    try {
                        Thread.sleep(2);
                    } catch (Exception e) {
                    }
                }
            } catch (EOFException ex) {
                System.out.println("client closed");
            }
        } catch (Exception ex) {
            Main.error("Server stopped for current host", ex);
        }
    }
}

конечно, конец команды намного умнее / элегантнее ...
[]]

...