Re: Sockets debugging tools
From: Andrei Voropaev (avorop_at_mail.ru)
Date: 02/17/05
- Next message: T Koster: "Re: Sockets debugging tools"
- Previous message: Gregory Toomey: "Re: Return Value of a Command"
- In reply to: T Koster: "Re: Sockets debugging tools"
- Next in thread: T Koster: "Re: Sockets debugging tools"
- Reply: T Koster: "Re: Sockets debugging tools"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 17 Feb 2005 09:43:52 GMT
On 2005-02-16, T Koster <reply-to-group@use.net> wrote:
> Andrei Voropaev wrote:
[...]
>> You are wrong. This is perfectly possible by programming your peer not
>> to read from the socket :) (Emulating the deadlock of the peer). In this
>> case after the system buffers are filled, your call to send will process
>> less (or even none) of the data. Note, system buffers are fairly large
>> so you may need to pass lots of data before they fill up. But they do
>> fill up. Tested :)
>
> Hmmm okay. So to start filling up the system's I/O buffers I just
> freeze the client program, and watch how my program handles send's
> inability to send?
>
> If so, what would happen if the client program never springs back to
> life, and the socket just remains in a permanent would-block state?
> After a while the OS will time-out the connection, right? Where is this
> error raised? The tcp(7) man page only specifies ETIMEDOUT but no
> indication of which calls raise it. Is is send and friends?
Nope. OS won't time-out the connection in this case. Your application is
responsible for handling such situations. For example by expecting
confirmation messages from peer within certain time and closing
connection if the confirmation does not come (yep, even with TCP
*sigh* :)
As to ETIMEDOUT error, this happens in the case where there was no route
to peer for a long time (pulled out network cable). The time is defined
by OS. Usually it is few minutes. The error is returned when you call
one of socket function (recv, send etc.) Supposedly the indication of
this error is also visible in poll (POLLERR) and select (err set). In
this case you can check the error using getsockopt with SO_ERROR option.
I use this for handling non-blocking connection on Linux.
[...]
> In addition to the ETIMEDOUT error, I'm confused about whether I need to
> look out for EPIPE or not. One man page (send(2)) tells me it is raised
> when "the local end has been shut down on a connected socket." Surely
> the local end only shuts down if I call close or shutdown on the socket,
> right? Thus, I already know when the local end has been shut down and
> such a socket would never be sent to anyway, or am I missing something?
> Another man page (tcp(7)) has something else to say about EPIPE: "The
> other end closed the socket unexpectedly or a read is executed on a shut
> down socket." This is totally different from what send(2) has to say,
> but sounds more likely. ip(7)'s story is similar to tcp(7), but not
> identical, plus I find the following unreassuring note under the BUGS
> section: "There are too many inconsistent error values." :(
EPIPE is important. You can't control it. Usually you get EPIPE when you
are writing the data and remote peer crashes. In this case your OS get's
back from peer EOF and closes "local end of pipe". But if your program
does not read at the moment, it does not get indication about that. And
during write it'll get SIGPIPE because the pipe is closed by OS already.
That's why I usually use send with MSG_NOSIGNAL option to convert
SIGPIPE to EPIPE. There are few other situations that lead to the same
scenario.
>
> ECONNRESET is elusive too: neither the ip(7) or tcp(7) man pages mention
> it. It only appears to be mentioned in send(2). Can it be expected to
> be raised by recv also? It makes more sense to me that recv should find
> out that a connection has been reset by the peer than send.
Quite opposite. CONNRESET is something that happens during sending. When
TCP attempts to deliver some data to the peer, and the peer has no idea
what to do with the data it sends back RST to indicate that connection
must be reopened. That situation is again normall for the case when peer
application crashes while your application is sending data. In practice
though I've never seen this error. Usually I get EPIPE :) I guess this
is so because computers are fast now. I call send to pass some data,
this goes into system buffer. Then it is passed to peer. In reply comes
RST. Local end gets closed and now I'm trying to send second portion.
Boom. SIGPIPE :)
>
> I would never have thought sockets programming on Linux would be so
> poorly-documented. I'm starting to read some FreeBSD man pages to see
> if they contain the details I'm missing.
Man pages are written in assumption, that those who read them know how
the protocol works. In other words, if you really want to write good
networking code you have to read some good books first, and then use man
pages only as memory refreshment or to find out specifics of
implementation for given OS :) I guess the authoritive book for
networking programming is one by Stevens "Unix Network Programming"
vol.1
-- Minds, like parachutes, function best when open
- Next message: T Koster: "Re: Sockets debugging tools"
- Previous message: Gregory Toomey: "Re: Return Value of a Command"
- In reply to: T Koster: "Re: Sockets debugging tools"
- Next in thread: T Koster: "Re: Sockets debugging tools"
- Reply: T Koster: "Re: Sockets debugging tools"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|