dash2 has asked for the wisdom of the Perl Monks concerning the following question:

(seeker of solace strings successive sibilants....)

OK, I am writing to a filehandle which represents a socket. To get unbuffered I/O, as much as possible, I use:

for (my $pointer = 0; $pointer < length($write); $pointer++) { syswrite (WHOIS, $write, 1, $pointer); }

The first time around, this works fine. However, sometimes I need to do this again (I need to recurse to a more specific WHOIS server to get useful WHOIS data, if you must know). So, I call the function again. It appears to work fine (I have checked the return value of syswrite(), and got a suitable number of "1"s) but the raw WHOIS data then appears as if I have only written the first character of $write to the new filehandle.

1) Am I normal? What's going wrong?

2) Is there a way I can check the data that is actually being sent out? Cos maybe their server is just being weird with me. (Update: doesn't seem to happen with other servers than this specific one. But doesn't seem to happen if I only connect once to this specific server.)

dave hj~

Replies are listed 'Best First'.
Re: syswrite strange behaviour on some systems
by AgentM (Curate) on Apr 02, 2001 at 20:46 UTC
    "To get unbuffered I/O, as much as possible..."

    That doesn't make sense. If you want unbuffered I/O on a socket, then set it using Fcntl or using the appropriate socket option. But why not skip "unbuffered" and flush as necessary. This loop is inefficient and serves no obvious purpose. In fact, it may be what's confusing the WHOIS server since your loop is quite possibly sending a packet at a time (system-specific). Perhaps your $write is not '\0' ended which the server may expect? This is really guesswork but the real solution is use the REAL methods of unbuffered I/O. Perhaps since you're iterating through a list of servers, you'll want this to speed things up a bit?

    AgentM Systems nor Nasca Enterprises nor Bone::Easy nor Macperl is responsible for the comments made by AgentM. Remember, you can build any logical system with NOR.
      Thanks AgentM

      Well, my $write always ends "\015\012". Which should be nice... sounds like I am confused about I/O though. I read the FAQ which says:

      Perl does not support truly unbuffered output (except insofar as you can `syswrite(OUT, $char, 1)').

      But the packet at a time thing sounds like it might be the problem...

      Update What is weird is that the syswrite loop runs OK with any other server but not this one.

      dave hj~

        Well, the FAQ is misleading (*sigh*). Perl does support unbuffered I/O via syswrite and sysread. Perhaps they meant that Perl doesn't support unbuffered I/O via other functions such as print and printf (except that you can have the buffer autoflushed as described).

        <Update> And the difference between unbuffered and "command buffered" (as the FAQ calls it) is pretty subtle and usually unimportant so you might as well use "command buffered" for most things. The only time that I think it matters is that you can get into trouble by mixing buffered and unbuffered I/O to/from the same file handle. Nothing external to your script should be able to tell the difference between the two. </update>

        In particular, you don't have to specify a write length of 1 in order for syswrite to be unbuffered. Also, I encourage you to just leave the length argument off and write syswrite(WHOIS,$write).

        By writing things one byte at a time, your data might get sent with as few as one byte per packet. I could see this confusing a poorly written server.

                - tye (but my friends call me "Tye")