Rozłączenie gniazda w TCP

0

Robię prosty programik, taki mini chat. Łącze klienta z serwerem po czym wymieniam informacje między nimi. Wszystko działa tylko mam problem bo chciałbym aby po wyłączeniu przez jednego z nich programu, drugiemu się wyświetliła prosta informacja o rozłączeniu rozmówcy, jednakże program mimo iż druga osoba sie rozłączyła nadal wydaje się połączony: client.isConnected() nadal zwraca true, a funkcja isClosed() false.

Gdy jeden klient kończy program wykonuję niniejsze instrukcje:

public void Disconnect() throws IOException{
                client.shutdownInput();
                client.shutdownOutput();
                outp.close();
                inp.close();
                if(client!=null)client.close();
                if(server!=null)server.close();
            }

Powyższa metoda zawarta jest w klasie Poloczenie.

A to linijka która niby źle działa:

if(!stan.client.isConnected()){
                dialog.setText(dialog.getText()+"\n"+stan.logint+" - został rozłączony"); 
                work=false;
            }else{
                try {
                    if(stan.inp.ready()){
                       cos = stan.Odbierz();
                    }
                } catch (IOException ex) {
                    Logger.getLogger(Chat.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

Te linijki są wykonywanie w drugim wątku tuż obok tego który odpowiada za interfejs (w swing).
Zaś stan to obiekt klasy Poloczenie, który posiada zarówno obiekt klasy SercerSocket (server) i Socket (client), a work to zmienna pętli drugiego wątku: "while(work)...". Obiekt inp to obiekt klasy BufferedReader pobierający strumień z sieci.

Błędów w kompilacji ani podczas uruchamiania nie ma a jednak nie działa jak powinno.
Podpowiedzcie i piszcie co ew. potrzebujecie aby my pomóc( co znaczy jaki element kodu ;)).

1

Możesz np co 1-2 sec wysyłać jakiś pakiet który client musi odesłać i jesli server wyśle ten pakiet a client go nie odbierze to server sypnie wyjątkiem i w tym momencie możesz sam zamknąć połączenie i wyświetlić info ze user 1 rozłączył się :)

0

Mało optymalne i wymagało by stworzenia nowego wątku.
Jakieś inne propozycje ? :(

0

Udało mi się znaleźć starszy temat na tym forum o podobnym problemie i byłem zmuszony zrobić to w podobny sposób:

if(stan.client.isConnected()){
                try {
                    if(stan.ready){
                       cos = stan.Odbierz();
                       if(cos==null){
                           work=false;
                           dialog.setText(dialog.getText()+"\n"+stan.loginj+" - został rozłączony");
                       } 
                    }
                } catch (IOException ex) {
                    Logger.getLogger(Chat.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

Link do tematu: Socket i zamkniecie polaczenia. .

A zasada działania polega na tym że gdy odebrany pakiet jest równy null wtedy przerywa . Pach i koniec.
A właśnie żeby nie było: metoda Odbierz zwraca String strumienia danych z gniazda drugiego użytkownika, piszę dla niejasności.

1 użytkowników online, w tym zalogowanych: 0, gości: 1