Що спричиняє помилку розбитої труби?


84

Я знаю, що помилка зламаної труби виникає, коли розетка на стороні однорангової мережі закрита.

Але в своєму тесті я зауважив, що негайний виклик "відправити" з цієї сторони, коли сторона однорангового зв'язку закрита, не завжди призводить до помилки поламаної труби.

Наприклад:

Після закриття сокета на стороні однорангової мережі (я спробував чисте закриття, зателефонувавши закрити, а також ненормальне закриття, вбивши одноранговий), якщо я спробую надіслати 40 байт, то я не отримую зламану трубу, але, якщо я намагаюся надішліть 40000 байт, тоді це негайно видає помилку пошкодженої труби.

Що саме спричиняє поломку труби та чи можна передбачити її поведінку?

Відповіді:


59

Для спостереження мережі, що знаходиться поруч, може знадобитися час - загальний час становить приблизно 2 хвилини (так, хвилини!) Після закриття, перш ніж всі пакети, призначені для порту, вважатимуться мертвими. Стан помилки виявляється в якийсь момент. З невеликим записом ви знаходитесь всередині MTU системи, тому повідомлення в черзі на відправлення. З великим записом ви перевищуєте MTU, і система швидше виявляє проблему. Якщо ви проігноруєте сигнал SIGPIPE, то функції повернуть помилку EPIPE на непрацюючу трубу - в якийсь момент, коли виявиться непрацездатність з'єднання.


4
@varevarao: Я не думаю, що чергування передач та відправлення через певні проміжки часу є обхідним шляхом. Черга передач, поки не буде надіслано більше, ніж MTU, може бути обхідним шляхом, якщо ваша програма може жити із затримками.
Джонатан Леффлер

11

Поточний стан сокета визначається діяльністю "збереження життя". У вашому випадку це можливо, що коли ви здійснюєте sendвиклик, keep-aliveдія повідомляє, що сокет активний, і тому sendвиклик запише необхідні дані (40 байт) в буфер і повернеться, не даючи жодної помилки.

Коли ви надсилаєте більший шматок, надсилання дзвінка переходить у стан блокування.

Сторінка відправки також підтверджує це:

Коли повідомлення не вміщується в буфер надсилання сокета, send () зазвичай блокується, якщо тільки сокет не був переведений у режим неблокуючого вводу-виводу. У неблокуючому режимі це поверне EAGAIN у цьому випадку

Отже, під час блокування для вільного доступного буфера, якщо абонент отримує повідомлення (за допомогою механізму підтримання активності), що інший кінець більше відсутній, виклик надсилання не вдасться.

Передбачити точний сценарій складно із згаданою інформацією, але я вважаю, що це має бути причиною для вас проблеми.


1
Поточний стан розетки спостерігається за активністю ACK. Keepalive - це лише одна незначна активність ACK-джерела, і вона за замовчуванням вимкнена.
Маркіз Лорнський

3

Можливо, 40 байт вміщується в буфер конвеєра, а 40000 байт ні?

Редагувати:

Процес надсилання надсилає сигнал SIGPIPE, коли ви намагаєтеся записати на закриту трубу. Я не знаю точно, коли надсилається сигнал, і який вплив на це має буфер конвеєра. Можливо, вам вдасться відновити, захопивши сигнал за допомогою дзвінка сигакції.


0

Коли одноранговий пристрій закривається, ви просто не знаєте, чи він просто перестає надсилати або одночасно надсилати та отримувати. Оскільки TCP дозволяє це, до речі, ви повинні знати різницю між закриттям та вимкненням. Якщо однорангові перестануть надсилати та отримувати, спочатку ви надішлете кілька байтів, це вдасться. Але однорангове ядро ​​надішле вам RST. Отже, згодом ви надсилаєте кілька байтів, ваше ядро ​​надішле вам сигнал SIGPIPE, якщо ви зловите або проігноруєте цей сигнал, коли ваше відправлення повернеться, ви просто отримаєте помилку Broken pipe, або якщо цього не сталося, поведінка вашої програми за замовчуванням аварійно завершує роботу .


-1

У нас з’явилася помилка Broken Pipe після встановлення нової мережі. Переконавшись, що порт 9100 був відкритий і міг підключитися до принтера через порт telnet 9100, ми змінили драйвер принтера з "HP" на "Загальний PDF", помилка непрацюючої труби зникла і ми змогли успішно надрукувати.

(RHEL 7, Принтери були брендом Ricoh, конфігурація HP була вже існуючою і функціонувала в попередній мережі)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.