Ah, EAGAIN and related issues will make more sense if you understand the underlying system calls, in this case write(2). There are a bunch of reasons a write can fail, and the EAGAIN error status indicates that the other end of the connection was not ready to receive input, which is almost always caused by a big queue of data which the receiving process simply hasn't looked at yet.
If syswrite returns undef, it will place the reason it returned undef into $!, which if evaluated numerically will yield the current value of the C "errno" variable. You can test for particulr errors explicitly like this:
use POSIX qw/EAGAIN EFBIG ENOSPC/;
# stuff
unless (defined(syswrite($socket,$buffer))) {
# Oops, didn't write. How come?
if ($! == EAGAIN) {
# Nonblocking and socket not yet ready...
} elsif ($! == EFBIG) {
# Writing to a file that is too big for our filesystem.
} elsif ($! == ENOSPC) {
# Ooops, writing to a file and the disk is full.
} else {
# One of the other dozen or so reasons a write can fail.
}
}
Now, in practice, you rarely need to worry about testing for errors like this. Blocking connections either work or fail permanently(Footnote 1). With non-blocking connections, if you make good use of the select(2) system call, your process will be told when sockets are ready to be read/written to. IO::Select is a wrapper to the select(2) system call which makes it a little more managable.
An excellent example of the skeleton needed for a non-blocking, non-forking server can be found in The Perl Cookbook, Section 17.13.
As to your original question of an example of using getpeername for detection, here's a short example:
unless (defined(syswrite($socket,$buffer))) {
# Oh dear, couldn't write. Could it be that I'm
# no longer connected?
if (defined(getpeername($socket))) {
# Yup, they're still there. Must be a different error.
} else {
# Oops, the other side went away.
}
}
I would strongly suggest using IO::Socket rather than using getpeername, simply because if($socket->connected) is much more understandable than the code above.
Hope that all this helps. I haven't had my morning coffee yet, so some bits might be a little unclear. Feel free to quiz me more if you like.
Cheers,
Paul
(Footnote 1) Not entirely true. Blocked reads and writes can be interrupted by signals, and I can't remember off the top of my head if perl automatically restarts the system call once you've dealt with the signal. |