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.


In reply to Re: Answer: How do i detect that the client has disconnected ? (i'm using sysread/write) by pjf
in thread How do i detect that the client has disconnected ? (i'm using sysread/write) by shlomi

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.