Wiem, że wyrzucany jest błąd pękniętej rury, gdy gniazdo po stronie równorzędnej jest zamknięte.
Ale w moim teście zauważyłem, że natychmiastowe wywołanie „wyślij” po tej stronie, gdy strona równorzędna jest zamknięta, nie zawsze prowadzi do błędu zerwanego przewodu.
Na przykład:
Po zamknięciu gniazda po stronie równorzędnej (próbowałem wyczyścić zamknięcie przez wywołanie close, a także nienormalne zamknięcie przez zabicie peera), jeśli spróbuję wysłać 40 bajtów, nie otrzymuję zepsutego potoku, ale jeśli spróbuję wyślij 40000 bajtów, a następnie natychmiast wyświetli błąd zepsutego potoku.
Co dokładnie powoduje pęknięcie rury i czy można przewidzieć jej zachowanie?
źródło
Bieżący stan gniazda jest określany przez aktywność „utrzymywania przy życiu”. W twoim przypadku jest to możliwe, że gdy wykonujesz
send
wywołanie,keep-alive
aktywność mówi, że gniazdo jest aktywne, więcsend
wywołanie zapisze wymagane dane (40 bajtów) do bufora i zwróci bez błędu.Kiedy wysyłasz większy fragment, wywołanie send przechodzi w stan blokowania.
Strona podręcznika wysyłania również to potwierdza:
Tak więc, podczas blokowania wolnego dostępnego bufora, jeśli dzwoniący zostanie powiadomiony (przez mechanizm utrzymywania aktywności), że drugi koniec nie jest już obecny, wywołanie wysyłające zakończy się niepowodzeniem.
Przewidywanie dokładnego scenariusza jest trudne przy wspomnianych informacjach, ale uważam, że to powinno być przyczyną twojego problemu.
źródło
Może 40 bajtów mieści się w buforze potoku, a 40000 bajtów nie?
Edytować:
Podczas wysyłania wysyłany jest sygnał SIGPIPE, gdy próbujesz pisać do zamkniętego potoku. Nie wiem dokładnie, kiedy sygnał jest wysyłany ani jaki wpływ ma na to bufor potoku. Możesz odzyskać równowagę, przechwytując sygnał za pomocą wywołania sigaction.
źródło
Kiedy peer jest blisko, po prostu nie wiesz, czy po prostu przestaje wysyłać, czy jednocześnie wysyła i odbiera, ponieważ TCP na to pozwala, przy okazji, powinieneś znać różnicę między zamknięciem a zamknięciem. Jeśli peer przestanie wysyłać i odbierać, najpierw wyślesz trochę bajtów, to się powiedzie. Ale jądro równorzędne wyśle Ci RST. Więc później wyślesz kilka bajtów, twoje jądro wyśle ci sygnał SIGPIPE, jeśli złapiesz lub zignorujesz ten sygnał, gdy twoja wysyłka wróci, otrzymasz błąd Broken pipe, lub jeśli nie, domyślne zachowanie twojego programu to awaria .
źródło
Wystąpił błąd zerwanej rury po zainstalowaniu nowej sieci. Po upewnieniu się, że port 9100 jest otwarty i może łączyć się z drukarką przez port telnet 9100, zmieniliśmy sterownik drukarki z „HP” na „Generic PDF”, błąd zepsutego przewodu zniknął i mogliśmy drukować pomyślnie.
(RHEL 7, Drukarki były marką Ricoh, konfiguracja HP była już istniejąca i działała w poprzedniej sieci)
źródło