Sé que se produce un error de tubería rota cuando el enchufe del lado del par está cerrado.
Pero, en mi prueba, noté que una llamada de 'enviar' inmediata en este lado cuando el lado del par está cerrado no siempre conduce a un error de tubería rota.
P.ej:
Después de cerrar el socket en el lado del par (he intentado un cierre limpio llamando close y también un cierre anormal al matar al par), si trato de enviar 40 bytes, entonces no obtengo una tubería rota, pero, si trato de envía 40000 bytes y luego inmediatamente da un error de tubería rota.
¿Qué causa exactamente la rotura de la tubería y se puede predecir su comportamiento?
fuente
El estado actual de un socket está determinado por la actividad de "mantener vivo". En su caso, es posible que cuando esté emitiendo la
send
llamada, lakeep-alive
actividad le diga que el socket está activo y, por lo tanto, lasend
llamada escribirá los datos requeridos (40 bytes) en el búfer y regresará sin dar ningún error.Cuando envía una porción más grande, la llamada de envío entra en estado de bloqueo.
La página del manual de envío también confirma esto:
Por lo tanto, mientras se bloquea el búfer libre disponible, si se notifica a la persona que llama (mediante el mecanismo de mantener vivo) que el otro extremo ya no está presente, la llamada de envío fallará.
Es difícil predecir el escenario exacto con la información mencionada, pero creo que esta debería ser la razón de su problema.
fuente
¿Quizás los 40 bytes quepan en el búfer de la tubería y los 40000 bytes no?
Editar:
El proceso de envío recibe una señal SIGPIPE cuando intenta escribir en una tubería cerrada. No sé exactamente cuándo se envía la señal o qué efecto tiene el búfer de tubería en esto. Es posible que pueda recuperarse capturando la señal con la llamada sigaction.
fuente
Cuando el par está cerca, simplemente no sabe si deja de enviar o si envía y recibe, ya que TCP permite esto, por cierto, debe conocer la diferencia entre cerrar y apagar. Si el par deja de enviar y recibir, primero envía algunos bytes, se realizará correctamente. Pero el kernel del mismo nivel le enviará RST. Entonces, posteriormente envía algunos bytes, su kernel le enviará la señal SIGPIPE, si capta o ignora esta señal, cuando su envío regresa, solo obtiene un error de tubería rota, o si no lo hace, el comportamiento predeterminado de su programa se bloquea .
fuente
Tuvimos el error de tubería rota después de que se instaló una nueva red. Después de asegurarnos de que el puerto 9100 estaba abierto y podía conectarse a la impresora a través del puerto Telnet 9100, cambiamos el controlador de la impresora de "HP" a "PDF genérico", el error de tubería rota desapareció y pudimos imprimir correctamente.
(RHEL 7, las impresoras eran de la marca Ricoh, la configuración de HP era preexistente y funcional en la red anterior)
fuente