Блокировка чтения () и готовности () сокета, обнаружение разъединения клиента - PullRequest
0 голосов
/ 01 февраля 2012

Хорошо, моя проблема проста. Я пытаюсь сделать простой чат, но я чувствую, что обнаружение отключенного клиента от сервера является обязательным. Чат работает нормально (без такого обнаружения), когда я использую простой:

                if (this.in.ready())  //preinitialized buffered reader
                    this.dataIn=this.in.readLine();

Я просмотрел множество сайтов / вопросов, опубликованных здесь, и я прочитал, что ready() следует пропустить, поскольку он блокирует все, что может быть правдой, поскольку, когда я удаляю этот ready(), мой чат больше не работает, однако он позволяет клиенту обнаружение отключено.

Чтобы достичь своей цели, мне нужно проверить, получает ли BufferedReader ноль через readLine(), но это также не работает так, как должно.

            if (this.in.readLine()!=null){ //1. check if client disconnected
                if (this.in.ready())       //2/
                    this.dataIn=this.in.readLine(); //3.
            }                    
            else
                this.notice="Client disconnected!";

Теперь, что происходит, когда я применяю код, представленный выше. Начальный, если (1) блокирует внутренний ready() (строка 2), который требуется для чтения фактического сообщения, отправленного через сокет (3).

Другой «порядок» не работает:

            if (this.in.ready()){
                this.dataIn=this.in.readLine();
            }
            else if (this.in.readLine()!=null)
                this.notice="Client disconnected!";

Этот также не позволяет отправлять сообщения через сокет.

* Да, отправка / получение осуществляется в отдельном потоке

* BufferedReader инициализируется только один раз

Исходный код потока (если таковой нужен 1 для просмотра):

    @Override
public void run() {
    try {
        if (this.isServer){            
            this.initServer();
            this.initProcessData(sSocket);
        } 
        else if (!this.isServer){
            this.initClient();
            this.initProcessData(clientSocket);
        }            
        this.initDone=true;

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

    while(this.initDone){
        try {
            Thread.sleep(100);
            if ((!this.dataOut.isEmpty())&&(this.dataOut!="")){                
                this.out.println(this.dataOut);
                this.out.flush();
                this.dataOut = "";
            }
            if (this.in.ready())
                this.dataIn=this.in.readLine();                   
        }
        catch (IOException ex) {
            Logger.getLogger(NetClass.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (InterruptedException ex) {  
            this.initDone=false;
                Logger.getLogger(NetClass.class.getName()).log(Level.SEVERE, null, ex);
        }

        //System.out.println(this.notice);
    }

}

Хуже всего то, что я либо правильно обнаружил, что клиент отключен, либо у меня есть рабочий чат.

Может ли кто-нибудь осветить меня, что мне делать, чтобы объединить эти два вместе? Любая помощь с благодарностью.

1 Ответ

0 голосов
/ 01 февраля 2012

Рассмотрите возможность использования java.io.ObjectInputStream и java.io.ObjectOutputStream.Используйте метод блокировки read() в отдельном рабочем потоке и выполняйте цикл, пока он не вернет -1 или не выдаст исключение.Отправляйте объекты String туда и обратно.Таким образом, вы также можете отправлять сообщения с переводами строки.

...