Подтвердить что ты не робот

Что вызывает ошибку Broken Pipe?

Я знаю, что ошибка разбитого трубопровода бросается, когда сокет на стороне сверстника закрыт.

Но в своем тесте я заметил, что немедленный вызов "Отправить" на этой стороне, когда закрыта сторона-сверст, не всегда приводит к ошибке разбитого трубопровода.

например:.

После закрытия сокета на стороне эксперта (я попытался выполнить чистое закрытие, вызвав close, а также аномальное закрытие, убив одноранговую сеть), если я попытаюсь отправить 40 байт, то я не получаю сломанный канал, но, если Я пытаюсь отправить 40000 байт, тогда он сразу же сообщает об ошибке поврежденного канала.

Что именно вызывает поврежденную трубу и может ли она быть предсказана?

4b9b3361

Ответ 1

Это может занять время для близкой к сети сети - общее время номинально составляет около 2 минут (да, минут!) после закрытия, прежде чем пакеты, предназначенные для порта, считаются мертвыми. Состояние ошибки обнаруживается в какой-то момент. С небольшой записью вы находитесь в MTU системы, поэтому сообщение помещено в очередь для отправки. С большой записью вы больше MTU, и система быстрее устраняет проблему. Если вы проигнорируете сигнал SIGPIPE, тогда функции возвратят ошибку EPIPE на сломанной трубе - в какой-то момент, когда обнаружена неисправность соединения.

Ответ 2

Текущее состояние сокета определяется активностью "keep-alive". В вашем случае возможно, что когда вы send вызов send, активность keep-alive говорит о том, что сокет активен, и поэтому вызов send будет записывать необходимые данные (40 байтов) в буфер и возвращается без каких-либо ошибка.

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

Страница отправки также подтверждает следующее:

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

Таким образом, блокируя свободный доступный буфер, если вызывающий абонент уведомляется (механизмом keep-alive), что другой конец больше не присутствует, вызов отправки не будет выполнен.

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

Ответ 3

Может быть, 40 байтов вписываются в буфер буфера, а 40000 байтов нет?

Edit:

Процесс отправки отправляется SIGPIPE-сигналом при попытке записи в закрытый канал. Я точно не знаю, когда посылается сигнал, или какое влияние на этот буфер буфера. Возможно, вы сможете восстановить, захватив сигнал с помощью вызова sigaction.

Ответ 4

Когда вы близки, вы просто не знаете, просто ли он прекратит отправку или отправку и получение. Поскольку TCP позволяет это, кстати, вы должны знать разницу между закрытием и выключением. Если вы оба прекращаете отправку и получение, сначала вы отправляете несколько байтов, это будет успешным. Но ядро peer отправит вам RST. Таким образом, впоследствии вы отправляете несколько байтов, ваше ядро отправит вам сигнал SIGPIPE, если вы поймаете или проигнорируете этот сигнал, когда ваша передача будет возвращена, вы просто получите ошибку Broken pipe, или если вы этого не сделаете, поведение вашей программы по умолчанию сбойное,