What causes the Broken Pipe Error?
Asked Answered
P

6

107

I know that broken pipe error is thrown when the socket on the peer side is closed.

But, in my test I have noted that an immediate 'send' call on this side when the peer side is closed doesn't always lead to a broken pipe error.

E.g.:

After closing the socket on peer side (I have tried clean closing by calling close and also abnormal closing by killing the peer), if I try to send 40 bytes, then I don't get a broken pipe, but, if I try to send 40000 bytes then it immediately gives broken pipe error.

What exactly causes broken pipe and can it's behavior be predicted?

Preference answered 3/1, 2011 at 13:39 Comment(0)
V
76

It can take time for the network close to be observed - the total time is nominally about 2 minutes (yes, minutes!) after a close before the packets destined for the port are all assumed to be dead. The error condition is detected at some point. With a small write, you are inside the MTU of the system, so the message is queued for sending. With a big write, you are bigger than the MTU and the system spots the problem quicker. If you ignore the SIGPIPE signal, then the functions will return EPIPE error on a broken pipe - at some point when the broken-ness of the connection is detected.

Vizard answered 3/1, 2011 at 16:55 Comment(3)
@varevarao: I don't think that queueing transmissions and sending at specific intervals is a workaround. Queuing transmissions until there's more than the MTU to send might be a workaround if your application can live with the delays.Vizard
I think that it's very related with en.wikipedia.org/wiki/Nagle%27s_algorithmSizemore
MTU: en.wikipedia.org/wiki/Maximum_transmission_unitMisfeasance
M
19

The current state of a socket is determined by 'keep-alive' activity. In your case, this is possible that when you are issuing the send call, the keep-alive activity tells that the socket is active and so the send call will write the required data (40 bytes) in to the buffer and returns without giving any error.

When you are sending a bigger chunk, the send call goes in to blocking state.

The send man page also confirms this:

When the message does not fit into the send buffer of the socket, send() normally blocks, unless the socket has been placed in non-blocking I/O mode. In non-blocking mode it would return EAGAIN in this case

So, while blocking for the free available buffer, if the caller is notified (by keep-alive mechanism) that the other end is no more present, the send call will fail.

Predicting the exact scenario is difficult with the mentioned info, but I believe, this should be the reason for you problem.

Mai answered 3/1, 2011 at 17:43 Comment(1)
The current state of the socket is observed by ACK activity. Keepalive is only one minor source ACK activity, and it is off by default.Mongeau
S
6

Maybe the 40 bytes fits into the pipe buffer, and the 40000 bytes doesn't?

Edit:

The sending process is sent a SIGPIPE signal when you try to write to a closed pipe. I don't know exactly when the signal is sent, or what effect the pipe buffer has on this. You may be able to recover by trapping the signal with the sigaction call.

Salvo answered 3/1, 2011 at 13:47 Comment(0)
D
2

When peer close, you just do not know whether it just stop sending or both sending and receiving.Because TCP allows this, btw, you should know the difference between close and shutdown. If peer both stop sending and receiving, first you send some bytes, it will succeed. But the peer kernel will send you RST. So subsequently you send some bytes, your kernel will send you SIGPIPE signal, if you catch or ignore this signal, when your send returns, you just get Broken pipe error, or if you don't , the default behavior of your program is crashing.

Dalmatia answered 14/9, 2018 at 6:8 Comment(0)
H
0

Session timeout settings may be the reason of broken pipe.
For example: Server session timeout 3 hours and load balancer has 1 hour.
Load balancer blocks after 1 hour, but server keeps sending response. In this case, one end of the pipe is broken.

But it can be also a user behavior. User closes the page during download etc.

Hartebeest answered 1/2, 2023 at 11:45 Comment(0)
I
0

You do not need to send code through a network to get this error. For example, this Python 3 code (now my favourite piece of code):

while 1:print()

will print a lot of newlines, and eventually a BrokenPipeError will be raised. So you will get this error if you write too much data to an IO or other stream.

Intelligence answered 17/8, 2023 at 7:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.