- 1
- 2
-
Dzemus
Jak wykryc fizyczne przerwanie polaczenia w komunikacji miedzy socketami - na przyklad chodzi mi serwer, a u klienta wyjmuje kabel...
Wiem, ze moge zrobic sobie pinga jakiegos, ale w naszym przypadku przesylamy sobie obiekty (ObjectInputStream itp) i jak kabel zostaje wyrwany w trakcie przesylania jednego obiektu, to Read staje na nim i tyle... Wiem, ze mozna zrobic TimeOuta, ale to generuje za kazdym razem wyjatek, co jest troche do bani, bo wiadomo, ze obsluga wyjatkow nie jest za szybka... -
Maciek Makowski
To sie w ogole da zrobic bez time-outa? Z tego co pamietam, interfejs socketow (na poziomie systemu operacyjnego) nie udostepnia informacji czy fizyczne polaczenie z drugim koncem istnieje -- ale moze zle pamietam.
Poza tym narzut czasowy na obsluge wyjatku jest chyba zaniedbywalny w porownaniu z czasem time-outa? Jaki masz konkretnie problem z uzyciem time-out w tej sytuacji? -
Hcorg
robie ten projekt razem z dzemusem wiec tez sie moze wypowiem :) Otoz probowalismy byc sprytni i umiescic wszystkich klientow w jednym watku i odpytywac ich w kolejce po stronie serwera. I tutaj timeout bylby nie wskazany no bo by zwolnilo troche :/ Ale timeout odpadl calkowicie kiedy probowalismy byc jeszcze bardziej wygodni i wysylac obiekty uzywajac ObjectOutput/InputStream - w tym wypadku przerwanie "zegarowe" powodowalo w nastepnej probie odczytu wyjatek "Stream corrupted". Wiec staralismy sie wymyslec cokolwiek co by pozowlilo ominac te bledy i zachowac przyjemnosc jednowatkowej obslugi klientow. Niestety im dluzej patrzymy tym bardziej widzimy ze raczej sie nie da :( Nie chcielismy miec po prostu od groma watkow dla kazdego klienta... -
Brut[all]
Nie mam zielonego pojęcia w temacie Java, ale..
Wyobraźcie sobie, że rozmawiacie przez krótkofalówkę ze swoim kolegą. W pewnym momencie kolegę ktoś zabija (ew. dla delikatnych - kolega mdleje, usypia, itp.). Skąd będziemy o tym widzieć, jeśli nie stąd, że nie odezwie się określoną ilość czasu? Powie nam o tym?
To dość logiczne.
Jeśli w połączeniu poprzez sieć jedna ze stron postanowi zamknąć połączenie (kolega mówi: "papa"), druga strona o tym natychmiast wie.
Jeśli jednak połączenie tak ni stąd, ni zowąd zostanie przerwane, nie dowiemy się o tym - możemy jedynie zgadywać, że dostalibyśmy coś już w odpowiedzi, gdyby ono nadal istniało.
Java nie może być tu wyjątkiem, bo do tego musiałaby chyba mieć zdoln.. ee.. algorytmy telepatii. -
-
Maciek Makowski
Brut[all]:
> Wyobraźcie sobie, że rozmawiacie przez
> krótkofalówkę ze swoim kolegą. W pewnym
> momencie kolegę ktoś zabija (ew. dla delikatnych
> - kolega mdleje, usypia, itp.). Skąd będziemy o
> tym widzieć, jeśli nie stąd, że nie odezwie się
> określoną ilość czasu? Powie nam o tym?
Zgadza się, z tym że w przypadku korzystnia z socketów mamy cały stos protokołów -- TCP lub UDP, pod spodem IP itd., tak że któraś z niższych warstw mogłaby zawierać jakiś mechanizm kontroli, czy ktoś na drugim końcu kabla (albo sygnału radiowego) "żyje". Z tym, że nieekonomiczne byłoby implementowanie tego na poziomie niższym niż warstwa transportu (TCP/UDP), dlatego wydaje mi się, że takiej kontroli się nie przeprowadza.
Hcorg, Dzemus:
Z tego co piszecie wynika, że jest to klasyczny przypadek, w którym należy zastosować wiele wątków. Nie do końca rozumiem problem z zepsutym strumieniem (jeśli był time-out, to znaczy że klient się rozłączył, zamykamy strumień i nie próbujemy już nic z niego czytać, nie? Czy chodzi o to, że na wierzchu dostajecie tylko "Stream Corrupted" i nie wiecie, czym było spowodowane?), ale tak czy inaczej na Waszym miejscu tworzyłbym osobny wątek dla każdego klienta.
Jest taka generalna zasada, że warto obecnie pisać aplikacje jak najbardziej współbieżne -- granica prędkości pojedynczego procesora krzemowego została już niemal osiągnięta, tak że już niedługo jedynym sposobem przyspieszania programów będzie zrównoleglanie obliczeń. Serwer odpytujący klientów to może nie jest akurat dobry reprezentant zadania z dziedziny High-Performance Computing, ale jeśli współbieżność da czytelniejszą architekturę i lepszą wydajność, to warto ją tu zastosować.
-
Brut[all]
"Zgadza się, z tym że w przypadku korzystnia z socketów mamy cały stos protokołów -- TCP lub UDP, pod spodem IP itd., tak że któraś z niższych warstw mogłaby zawierać jakiś mechanizm kontroli, czy ktoś na drugim końcu kabla (albo sygnału radiowego) "żyje". Z tym, że nieekonomiczne byłoby implementowanie tego na poziomie niższym niż warstwa transportu (TCP/UDP), dlatego wydaje mi się, że takiej kontroli się nie przeprowadza. "
A więc siądź i napisz taki protokół, ciekawym, jak Ci wyjdzie :)
Powtarzam: nie jest to ograniczenie nałożone przez istniejące protokoły, a.. a przez najprostszą logikę. Jak Ty byś chciał to niby zrealizować?
Na protokoły telepatii to chyba jeszcze troszkę za wcześnie. -
Dzemus
No właśnie w tym wypadku nie daje ani czytelniejszej architektury ani lepszej wydajnosci :/ Bo (wiadomo) im więcej wątków tym większa zabawa z synchronizacją - bo jak mieliśmy wszystko w jednym to nie było problemem przelecenie po wszystkich Streamach i sprawdzenie czy nie mają nam czegoś do powiedzienia :P A tak będzie trzeba synchronizować (no w sumie synchro w Javie jest banalne, ale jednak dodatkowy narzut). A po drugie lepsza wydajność nie będzie, bo w momencie jak będziemy mieli na raz 60 klientów podłączonych (lekko licząc :P), to 2/3 czasu procesora będzie zajmowało przełączanie między wątkami (nawet przy założeniu, że mamy 2 albo 3 rdzeniowy serwer :P)...
Właśnie myśleliśmy, że jest jakaś funkcja Socketa sprawdzająca połączenie, niestety isConnected() sprawdza czy połączenie zostało nawiązane, nie patrząc czy dalej trwa :/ Właśnie brakuje jakiegoś niskopoziomowego "pinga". Bo w sumie wszystko grało, dopóki nie wpadliśmy z Hcorgiem na genialny pomysł wyjęcia kabla sieciowego i sprawdzenia co się będzie działo :|
Po googlaniu odkryliśmy coś takiego jak SO_KEEPALIVE, który teoretycznie powinien zgłosić zerwanie połączenia... W sockecie można go nawet włączyć, niestety nie da się ustawić czasu po jakim sprawdza połączenie.. Domyślnie (o ile google prawdę mówią) jest to 20 min (sic!) :/
No innymi słowy paranoja i chyba faktycznie będzie trzeba zrobić na wątkach.. A byliśmy tacy zadowoleni jak nam się "teoretycznie" udało to zrobić wszystko w jednym wątku :| -
Maciek Makowski
> Powtarzam: nie jest to ograniczenie nałożone
> przez istniejące protokoły, a.. a przez najprostszą
> logikę. Jak Ty byś chciał to niby zrealizować?
Napisałem:
"któraś z niższych warstw mogłaby zawierać jakiś mechanizm kontroli, czy ktoś na drugim końcu kabla (albo sygnału radiowego) "żyje""
To znaczy, że np. system wysyłania potwierdzeń i time-outów mógłby być zrealizowany w warstwie sieciowej, w ramach protokołu IP. Interfejs socketów ukrywałby to przed użytkownikiem tak, że ten nie musiałby stosować własnych time-outów (o to kolegom chodziło).
Inna sprawa, że byłoby to nieekonomiczne -- bo konieczność wysyłania potwierdzeń zmniejsza wydajność, a niektórym protokołom wyższej warstwy tego rodzaju informacje nie są do niczego potrzebne -- więc stwierdziłem, że tego typu rozwiązań zapewne się w niższych warstwach nie stosuje.
Pewnego rodzaju kontrolę mogłabyby jednak w niektórych przypadkach realizowalna praktycznie. Np. w warstwie fizycznej używającej kabla: interfejs sieciowy puszcza w kabel prąd i sprawdza, czy obwód jest zamknięty. Jak drugą końcówkę wepnie się w drugi interfejs sieciowy, to ten zamyka obwód. Jak obwód się zamyka, interfejs sieciowy generuje odpowiednie przerwanie. Jak obwód się otwiera, generuje inne przerwanie.
Ogólnie, jak przesyła się dane używając pewnego podstawowego sygnału jako nośnego, a informacje koduje modulując ten sygnał nośny, to zanik sygnału nośnego świadczy o tym, że urządzenie na drugim końcu przerwało transmisję. Oczywiście, nie ma implikacji w drugą stronę, ale pewne przypadki można w ten sposób obsłużyć. -
Dzemus
-
Brut[all]
Eee..
"To znaczy, że np. system wysyłania potwierdzeń i time-outów mógłby być zrealizowany w warstwie sieciowej, w ramach protokołu IP. Interfejs socketów ukrywałby to przed użytkownikiem tak, że ten nie musiałby stosować własnych time-outów (o to kolegom chodziło).
Inna sprawa, że byłoby to nieekonomiczne -- bo konieczność wysyłania potwierdzeń zmniejsza wydajność, a niektórym protokołom wyższej warstwy tego rodzaju informacje nie są do niczego potrzebne -- więc stwierdziłem, że tego typu rozwiązań zapewne się w niższych warstwach nie stosuje."
Proponuję przejrzeć snifferem dane przechodzące przez Twoją kartę sieciową.
Protokół TCP/IP STOSUJE potwierdzanie wysłanych danych, STOSUJE kontrolę i to właśnie od niego wychodzi timeout.
I co to zmienia? W jaki sposób to najniższe z miejsc ma dojść do tego, że połączenie zostało przerwane? Ono również zdolności telepatii nie posiada.
Tego nie może stwierdzić ani protokół, ani nawet sieciówka - do tego nie można w żaden sposób dojść, przyglądając się surowym stosunkom napięć na kablu.
Bo i jak?
"Ogólnie, jak przesyła się dane używając pewnego podstawowego sygnału jako nośnego, a informacje koduje modulując ten sygnał nośny, to zanik sygnału nośnego świadczy o tym, że urządzenie na drugim końcu przerwało transmisję. Oczywiście, nie ma implikacji w drugą stronę, ale pewne przypadki można w ten sposób obsłużyć."
Tak, tylko chyba zapominasz o dość sporej różnicy między działaniem sieci, a jakiegoś układu elektro-mechanicznego.
W tym pierwszym sygnał nośny nie jest ciągły i stały w czasie, sygnał przychodzi pakietowo - nie ma jakiegoś konkretnego śr 5V, jest śr. 20 * śr. 200B na sekundę, nie istnieje coś takiego, jak "zanik sygnału", bo ten sygnał zanika po kilkadziesiąt razy na sekundę w przerwie między kolejnymi pakietami. Jedyną możliwością rzeczywistego sprawdzenia, czy sygnał zanikł, jest ustalenie sobie jakiegoś odcinka czasu, który w teoretyce nie może wystąpić pomiędzy sąsiednimi pakietami danych. I to jest właśnie nazwane time-outem.
A spróbuj mi opisać teoretycznie zasadę działania beztimeoutowego wykrywacza utraty połączenia w transmisji pakietowej... -
spec
nono, to byl ladny watek i podoba mi sie bardzo sposob w jaki rozpoczeliscie dyskusje; >
-
Dzemus
Generalnie chodzi o to, że skoro Java jest taka intuicyjna i w ogóle wszystko za nas robi, to czemu nie można sobie zrobić
Socket s = new blablabla;
s.enableConnectionCheck(true);
if (s.isReallyConnected()) { }
?
No generalnie lekko irytujące. Mogliby zrobić pinga wbudowanego, skoro już tyle innych rzeczy mniej przydatnych powrzucali :|
Od razu uprzedzę wasze posty - tak mógłbym sobie to sam napisać, przy zczytywaniu bajt po bajcie to nawet nietrudne by było, tyle, że się chcieliśmy wycwanić i skoro Java daje możliwość przesyłania obiektów, to czemu nie?
No dobra, nie będę się żalił, bo nic konstruktywnego nie wnoszę... Peace. -
Maciek Makowski
Dobra, tego rodzaju dyskusji chciałem uniknąć, bo, jak wspomniałem na początku w technikaliach działania sieci nie jestem mocny. Ale wydaje mi się, że pewne rzeczy jeszcze pamiętam:
> Proponuję przejrzeć snifferem dane przechodzące
> przez Twoją kartę sieciową.
> Protokół TCP/IP STOSUJE potwierdzanie
> wysłanych danych, STOSUJE kontrolę i to właśnie
> od niego wychodzi timeout.
TCP i IP to są dwa oddzielne protokoły, pochodzące z różnych warstw modelu OSI ( http://en.wikipedia.org/wiki/Osi_mo... IP jest protokołem pakietowym, w którym/ dostarczenia pakietu nie potwierdza się/ (fragmentu między/ / nie jestem pewiem, poprawcie mnie, jeśli się mylę). TCP jest protokołem strumieniowym na bazie IP, gwarantującym dostarczenie danych -- jeśli z drugiego końca w odpowiednim oknie czasowym nie nadejdzie potwierdzenie odebrania danych, dokonywana jest retransmisja "zgubionej" części. Time-outy zaimplementowane są w ramach TCP, na samym wierzchu tego, co oferuje socket, więc wyjątki wyrzucane są bezpośrednio do aplikacji, która z socketu korzysta. W proponowanym przeze mnie rozwiązaniu time-out byłby na poziomie protokołu IP. Różnica byłaby w interfejsie socketa -- informacja o time-oucie nie byłaby udostępniana użytkownikowi, ten znałby jedynie stan połączenia.
Z tym, że jak wspomniałem byłoby to marnotrawstwo, bo np. UDP (alternatywny do TCP protokół warstwy transportu, stosujący transmisję pakietową) takich potwierdzeń nie potrzebuje. Poza tym rozwiązanie takie byłoby mniej elastyczne, bo użytkownik nie miałby z poziomu aplikacji kontroli nad time-outem. Stąd wnioskuję, że takie rozwiązanie nie jest stosowane, ale jak się rzeczy mają w rzeczywistości -- nie wiem.
> Tak, tylko chyba zapominasz o dość sporej
> różnicy między działaniem sieci, a jakiegoś
> układu elektro-mechanicznego.
> W tym pierwszym sygnał nośny nie jest ciągły i
> stały w czasie, sygnał przychodzi pakietowo -
> nie ma jakiegoś konkretnego śr 5V, jest śr. 20
> * śr. 200B na sekundę, nie istnieje coś takiego,
> jak "zanik sygnału", bo ten sygnał zanika po
> kilkadziesiąt razy na sekundę w przerwie
> między kolejnymi pakietami. Jedyną
> możliwością rzeczywistego sprawdzenia, czy
> sygnał zanikł, jest ustalenie sobie jakiegoś
> odcinka czasu, który w teoretyce nie może
> wystąpić pomiędzy sąsiednimi pakietami
> danych. I to jest właśnie nazwane time-outem.
> A spróbuj mi opisać teoretycznie zasadę
> działania beztimeoutowego wykrywacza utraty
> połączenia w transmisji pakietowej...
Wyobraź sobie, że protokół warstwy łącza działa tak, że sygnał ma dwa możliwe poziomy (oczywiście mierzone z jakąś tolerancją). Poziom sygnału próbkowany jest z zadaną częstotliwością. Przyjmijmy, że 0 oznacza, że poziom nie zmienił się od ostatniej próbki, a 1, że się zmienił. Urządzenie chcące odczytać ciąg bitów odczytuje wartości kolejnych próbek i co trzy próbki sprawdza, co dostało:
011 (brak zmiany, zmiana, zmiana): 1
101: 0
111: brak danych (ale urządzenie na drugim końcu jest aktywne -- to jest Twoja "przerwa między pakietami")
cokolwiek innego: urządzenie na drugim końcu nie jest podłączone/nie funkcjonuje prawidłowo. Przerwanie transmisji wykryte zostanie najpóźniej po dwóch próbkach.
Chyba, że to też uważasza za time-out? Jeśli tak, to będę musiał pomyśleć nad rozwiązaniem analogowym, bo w cyfrowym świecie wszystko jest skwantowane... -
Maciek Makowski
> Wyobraź sobie, że protokół warstwy łącza działa tak [...]
Niepotrzebnie to wszystko uszczegolowilem I skomplikowalem. Pomysl jest po prostu taki, jak napisalem poprzednio -- jest jakis sygnal nosny i jak on znika to wiemy, ze polacznie zostalo przerwane. Ty piszesz, ze "sygnal nosny nie jest ciagly" i ze "zanika kilka razy na sekunde". No wlasnie nie musi w ogle znikac, wystarczy, zeby caly czas bylo jakies napiecie, a dane kodowalo sie poprzez zmiany poziomu tego napiecia. Wtedy jak napiecie zniknie wiemy od razu, ze polaczenie zostalo przerwane. -
Brut[all]
Tak, tylko że znów niepotrzebnie przechodzisz w elektrykę, bo w świecie informatyki takim kablem przechodzi jednocześnie kilka tysięcy, zupełnie nie związanych ze sobą, informacji, więc żadna z nich nie jest podawana przez cały, każde połączenie jest wciąż przerywane na rzecz innych.
Tworzenie jakiegoś arbitrażu, typu: "po kolei po 1KB z każdego strumienia i od początku", co by faktycznie sprawdziło połączenie w odpowiednim momencie, oczywiście, nie ma żadnego sensu, ponieważ dane internetowe nie są w żaden sposób symetryczne, nie mają określonej stałej przepustowości, wielkości pakietów, czy ich gęstości - są zupełnie przypadkowe. -
nablaone
Ustaw SO_KEEPALIVA = true i mały timeout. Stos TCP/IP szybko stwierdzi, że jest coś nie tak z połączeniem fizyczynym i ci rzuci Jav wyjątek przy czytaniu.
O co chodzi z tym, że obsługa wyjątków jest wolna? W czym ci to przeszkadza?
-
Dzemus
No żeby przełączyć się między wątkami (kiedy nie masz tylu rdzeni w procku ile wątków) musisz zapamiętać sobie wszystkie informacje o bieżącym wątku (zgubiłem mądre słowo opisujące te informacje..), przepiąć wskaźnik, wczytać info o nowym wątku, pomemłać pomemłać, znowu zapisać, znowu przepiąć, znowu odczytać..
Wszystkie predykaty skoków idą do piachu, narzut na przełączeniu koszmarny.
Wiem, że to Java i tak czy tak jest wolna, ale mamy jakieś głupie przyzwyczajenia z C/C++, żeby jednak pisać tak, żeby procek nie musiał się męczyć podczas wykonywania, a co za tym idzie jeszcze bardziej nie spowalniać Javy...:| -
Dzemus
Aaaaj.. sorki.. Źle przeczytałem.. nie wątków, tylko wYjątków... Ano w tym, że np. w C robisz sobie porównanie wyniku funkcji do nulla albo -1 i jest luz - jedna operacja procka i cześć... A wyjątek trzeba rzucić, złapać, obsłużyć - i się trochę tego mnoży... -
spec
to pisz w c++.
cos o watkach..
przelaczanie watkow jest zaimplementowane na x86 sprzetowo od wielu lat, nie mowiac o ht na p4.
w zasadzie to 32bitowe pm juz zapewnia Ci przelaczenie watku z wlasna przestrzenia adresowa, i zapamietaniem ramki stosu i rejestrow.
wirtualna maszyna pewnie korzysta z mechanizmu ktory jest w systemie.wiadomo.
coz wybieramy albo wygode i szybkosc pisania. albo szybkosc dzialania.
java JEST wolna.
--
peace! -
Dzemus
O sprzętowym przełączaniu wiem - i właśnie przy okazji sprzętowego przełączania mówiono mi o tym, że jeżeli dorzuca się do programu wątek to trzeba się 7 razy zastanowić czy jest to absolutnie konieczne.
(tak samo jak porównywanie do wartości innych niż zero albo kolejność deklarowania zmiennych.. albo inne kruczki programistyczne których uczyli mnie na Architekturze Komputerów przyśpieszające nam program o 0,001% :P :P)
- 1
- 2
- Przeglądaj grona w kategorii Internet i Komputery
- Przeglądaj grona w okolicy Warszawa
- Załóż własne grono tematyczne
- Zostań moderatorem
Podobne Tematy
|
|
Wszystko co związane z programowaniem w Java (J2EE, JSP, JDBC, itd) test
Miejsca grona (1)
-
Kino Luna ul. Marszałkowska, Warszawa
www.kinoluna.pl kino.luna@maxfilm.com.pl 22 621 78 28
- Dodaj miejsce

