• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[Java] Jak sprawdzić czy socket jest aktualnie połączony?

VPS Starter Arubacloud
0 głosów
430 wizyt
pytanie zadane 15 stycznia 2019 w Java przez ILikeJava Obywatel (1,230 p.)

Ja sprawdzić czy socket jest aktualnie połączony? 

public void run() {
        while (true) {
            try {
                if (socket.isConnected()) {
                    System.out.println("is actuaally conecting");
                    input = new ObjectInputStream(socket.getInputStream());
                    Message messagePing = (Message) input.readObject();
                    if (messagePing.getMessage().equals("ping") &&
                            messagePing.getAuthor().equals(name)) {
                        localOutput = new ObjectOutputStream(socket.getOutputStream());
                        localOutput.writeObject(new Message(CONFIG, "pong"));

                        Message message = (Message) input.readObject();
                        if (message.getHeader().equals(USERMESSAGE)) {
                            if (usersBase.getUser(message.getRecipient())!= null) {
                                output = new ObjectOutputStream(socket.getOutputStream());
                                output = new ObjectOutputStream(usersBase.getUser(
                                        message.getRecipient()).getSocket().getOutputStream());
                                output.writeObject(message);
                            } else { System.out.println("user is null"); }
                        }
                    }
                }
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

socket.isConnected() (4 linijka) nie działa bo gdy rozłączę klienta to jest ciągle błąd przez rozłączonego socketa. Z góry dzięki za pomoc.

1 odpowiedź

0 głosów
odpowiedź 16 stycznia 2019 przez mbabane Szeryf (79,280 p.)

Wydaje mi się, że sytuację, którą opisujesz nie należy traktować jako wyznacznik tego, czy klient jest podłączony czy nie. To co opisujesz to jest nieoczekiwane zerwanie połączenia przez klienta. Poprawnie, z tego co się orientuje trzeba robić tak, że jeśli klient kończy połączenie to wysyła do serwera komunikat "Hej rozłączam się". Jest to wtedy poprawna forma skończenia połączenia.

A to co opisujesz to jest sytuacja kiedy klient nagle zostanie zerwany bo np. ktoś wyjął kabel od internetu i dla serwera nie jest to sytuacja normalna tylko wyjątkowa. Do takich celów zostały własnie przygotowane wyjątki IOException. Jeśli read czy write rzuca taki wyjątek oznacza, że klient'a nie ma. Bo nie można tego zrobić w ten sposób, że przed użyciem np. writeObject, zrobisz sobie if'a w stylu, "jeśli klient jest podłączony, to zrób write", bo co jeśli przesyłasz np. duży obiekt, zajmujący np. 1GB i w trakcie wysyłki po przesłaniu 100MB ktoś odłączy kabel od sieci.

Metoda isConnected z tego co zrozumiałem ze stacka zwraca true jeśli chociaż raz udało się uzyskać połączenie. W dokumentacji np. jest takie zdanie:

Note: Closing a socket doesn't clear its connection state, which means this method will return true for a closed socket (see isClosed()) if it was successfuly connected prior to being closed.

Czyli z tego wynika, że podłączając się pomyślnie do gniazda, po jego zamknięciu isConnected dalej będzie zwracało true, bo zostało zarejestrowanie pomyślne połączanie .

Dlatego jeśli potrzebujesz w aplikacji mechanizmu, który będzie Ci sprawdzał czy dany klient jest podłączony (w sensie jako funkcjonalność tzn. np. przycisk sprawdzający czy klient jest online) to chyba trzeba do tego celu napisać coś na zasadzie pinga. Wysyłasz po prostu do klienta wiadomość w stylu, "Hej czy jesteś", on odpowiada "Tak" lub rzuca wyjątek (IOException) w przypadku gdy wiadomość nie dotrze.  A w aplikacji po prostu będziesz musiał obsłużyć ten wyjątek w taki sposób aby wyświetlany był komunikat, że klient jest w stanie offline.

Niestety, albo "stety", Socket i SocketServer to mechanizmy dość niskopoziomowe i pewne rzeczy trzeba samemu ogarniać, jak np. własnie to co Ty masz.

komentarz 16 stycznia 2019 przez ILikeJava Obywatel (1,230 p.)

Dzięki. 

Dlatego jeśli potrzebujesz w aplikacji mechanizmu, który będzie Ci sprawdzał czy dany klient jest podłączony (w sensie jako funkcjonalność tzn. np. przycisk sprawdzający czy klient jest online) to chyba trzeba do tego celu napisać coś na zasadzie pinga. Wysyłasz po prostu do klienta wiadomość w stylu, "Hej czy jesteś", on odpowiada "Tak" lub rzuca wyjątek (IOException) w przypadku gdy wiadomość nie dotrze.  A w aplikacji po prostu będziesz musiał obsłużyć ten wyjątek w taki sposób aby wyświetlany był komunikat, że klient jest w stanie offline.

To ma być osobny wątek który non stop pyta się klienta? Dobrze rozumiem? 

komentarz 17 stycznia 2019 przez mbabane Szeryf (79,280 p.)

Generalnie poszperaj jeszcze trochę w internetach bo pewnie jest na to jakieś ciekawe rozwiązanie, i pewnie lepsze od mojego.

To ma być osobny wątek który non stop pyta się klienta?

To zależy od funkcjonalności. Jeśli ma to być cały czas wyswietlane (tzn. takie auto odświeżalne) to pewnie tak to trzeba zrobić, że pyta klienta np. co 10 sekund. Natomiast jeśli ma to być pod przyciskiem, tak że klikasz go i pokazuje status to pewnie da radę bez wątku.

Podobne pytania

0 głosów
1 odpowiedź 456 wizyt
pytanie zadane 30 czerwca 2018 w JavaScript przez Kamil Batorski Obywatel (1,870 p.)
+1 głos
1 odpowiedź 97 wizyt
pytanie zadane 11 stycznia w Java przez Specjalny Nowicjusz (230 p.)
0 głosów
0 odpowiedzi 2,801 wizyt
pytanie zadane 7 maja 2018 w Java przez Patryk8090 Użytkownik (520 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...