Mam połączenie tcp w gnieździe między dwiema aplikacjami java. Kiedy jedna strona zamyka gniazdo, druga strona pozostaje otwarta. ale chcę, żeby była zamknięta. A także nie mogę się doczekać, czy będzie dostępny, czy nie, a po tym zamknąć. Chcę w jakiś sposób całkowicie go zamknąć z jednej strony. Co mogę zrobić?Czy można zamknąć gniazda Java po stronie klienta i serwera?
Odpowiedz
TCP nie działa w ten sposób. System operacyjny nie zwolni zasobów, a mianowicie deskryptora pliku, a tym samym portu, dopóki aplikacja jawnie nie zamknie gniazda lub nie zginie, nawet jeśli stos TCP wie, że druga strona go zamknęła. Nie ma wywołania zwrotnego od jądra do aplikacji użytkownika po otrzymaniu FIN od peera. System operacyjny potwierdza to drugiej stronie, ale czeka, aż aplikacja zadzwoni pod numer close()
przed wysłaniem pakietu FIN. Spójrz na numer TCP state transition diagram - znajdujesz się w polu pasywnym zamykającym .
Jednym ze sposobów wykrycia takiej sytuacji bez dedykowania wątku do każdego gniazda jest użycie rodziny funkcji select/poll/epoll/kqueue
. Gniazdo, które jest pasywnie zamknięte, zostanie zasygnalizowane jako czytelne, a próba odczytu zwróci EOF.
Mam nadzieję, że to pomoże.
Obie strony muszą odczytać połączenie, aby mogły wykryć zamknięcie peera. Kiedy read zwraca -1 oznacza to, że drugi koniec zamknął połączenie i to jest Twoja wskazówka, aby zamknąć swój koniec.
Mój kod to wielowątkowy kod i nie mogę marnować jednego z moich wątków, szukając tylko połączenia i sprawdzając, czy jest zamknięty, czy nie. Powinienem wspomnieć, że mam tysiące takich połączeń, nie tylko jeden. – Shayan
Następnie musisz przełączyć na NIO i wykonać multipleksowane IO. Musisz czytać z gniazda w ten czy inny sposób, jeśli chcesz wykryć pełne wdzięku zbliżenie od rówieśnika. – nos
Prawdopodobnie chcesz mieć pulę połączeń.
Nie. Po prostu automatycznie zamyka się połączenie. – Shayan
Jeśli nadal czytasz z gniazda, wykryjesz wartość -1 po jej zamknięciu.
Jeśli nie czytasz już z gniazda, zamknij je.
Jeśli nie jest to żadna z tych rzeczy, prawdopodobnie oczekujesz wątku na zdarzenie. NIE jest to sposób, w jaki chcesz obsłużyć tysiące portów! Java zacznie dostawać pukey na około 3000 wątków w oknach - o wiele mniej w Linuksie (nie wiem dlaczego).
Upewnij się, że używasz NIO. Użyj jednego wątku do zarządzania wszystkimi portami (pulą połączeń). Powinien po prostu pobrać dane z wątku, przekazać je do kolejki. W tym momencie wydaje mi się, że mam pulę wątków, która pobiera dane z kolejek i przetwarza je, ponieważ przetwarzanie danych z portu zajmuje trochę czasu.
Dołączanie wątku do każdego portu NIE działa i jest najważniejszym powodem, dla którego NIO było potrzebne.
Ponadto, posiadanie pewnego rodzaju komunikatu "Zamknij" jako części twojego strumienia, aby aktywować zamykanie portu, może przyspieszyć działanie - ale nadal musisz obsłużyć -1, aby pokryć przypadek zepsutych strumieni
Ta strona nie wie, czy jest ukończona, czy nie.Wysyłanie zbyt dużej wiadomości z drugiej strony jest zbyt duże. większość razy dla jednej wiadomości wysyłamy dwie wiadomości. – Shayan
Nie jestem pewien co masz na myśli, ale możesz po prostu zakończyć wiadomość specjalną postacią lub kodem bajtowym, aby powiedzieć słuchaczowi, że to ostatnia wiadomość. To prawie za darmo. –
Jeśli wysłanie kilku dodatkowych bajtów, aby zasygnalizować, że zamknięcie jest zbyt duże, masz albo specjalne wymagania, albo cierpisz na przedwczesną optymalizację. – Confusion
Zazwyczaj rozwiązaniem jest poinformowanie drugiej strony, że zamierzasz zamknąć połączenie, zanim je zamkniesz. Na przykład w przypadku protokołu SMTP serwer wyśle komunikat "221 Bye", zanim zamknie połączenie.
Mimo że jest to dobra optymalizacja, nie będzie obsługiwać zerwanych połączeń, a ostatecznie utworzysz otwarte porty. Jest to niedopuszczalne w przypadku systemu z tysiącami otwartych portów, ale zmniejsza częstotliwość skanowania "Czy mogę zamknąć ten port". –
- 1. Wymuszanie uwierzytelniania Facebook: po stronie klienta i po stronie serwera
- 2. Logika po stronie klienta LUB logika po stronie serwera?
- 3. Pomiar czasu reakcji serwera (po stronie klienta)
- 4. Kiedy korzystać po stronie klienta lub po stronie serwera?
- 5. Języki po stronie klienta
- 6. rozłącz klienta od strony serwera po stronie
- 7. Webpack: Ignoruj biblioteki klienta po stronie serwera
- 8. CSS po stronie serwera?
- 9. Jak logicznie połączyć router reagujący i redux do renderowania po stronie klienta i po stronie serwera?
- 10. Czy można utworzyć czysto po stronie klienta aplikację GWT?
- 11. Renderuj różne komponenty po stronie klienta i serwera.
- 12. Nie można otworzyć pliku po stronie klienta, próbując po stronie serwera.?
- 13. Przekierowania po stronie serwera
- 14. Uwierzytelnianie użytkowników G + po stronie serwera, po zalogowaniu po stronie klienta
- 15. GWT I18N po stronie serwera
- 16. Reagowanie po stronie serwera i po stronie klienta nie jest płynne
- 17. Połączyć uwierzytelnianie po stronie serwera i po stronie klienta z WebAPI
- 18. Przycinanie i przesyłanie obrazu po stronie klienta bez kodu po stronie serwera obejmuje
- 19. module.exports po stronie klienta
- 20. Język szablonowania po stronie klienta z kompilatorem java (szablon DRY)
- 21. Emberjs, strona serwera po stronie klienta, wszystko w?
- 22. Przeglądarka po stronie serwera
- 23. po stronie serwera w Meteor
- 24. Gniazda RAII: kiedy wydać (zamknąć)
- 25. Nie blokujące się gniazda klienta i serwera w C
- 26. Meteor Npm-moduł po stronie klienta?
- 27. PHP - certyfikat klienta gniazda SSL
- 28. Skanowanie po stronie serwera
- 29. Jak czekać po stronie klienta, aż połączenie z Mongo po stronie serwera jest gotowe?
- 30. Czy jest możliwe uruchomienie serwera gniazd i klienta gniazda na tym samym komputerze?
Łącze diagramu stanu połączenia TCP daje 404 –