in reply to read aka fread(3) broken, sysread aka read(2) works IIS socket

antirice provides a valuable observation. The underlying issue is this: read() buffers; sysread() doesn't. This matters when the socket is still open, as it will be when you use the   Connection: Keep-Alive header. This tells the web server that you expect to reuse the socket for additional requests. The web server obliges by keeping the socket open and by sending a Content-Length header in the response to tell you exactly how many bytes it is safe for you to read. If you try to read more, you'll block.

read(), given a buffer size to read, will wait for the socket to fill up the buffer, and will block until more bytes are available. sysread() will return the number of bytes that are actually available.

Alternatively, you could use the Content-Length that the web server has returned to you (and which you've squirreled away in $length), and read() only that many bytes.

Replies are listed 'Best First'.
Re: Re: read aka fread(3) broken, sysread aka read(2) works IIS socket
by antirice (Priest) on Sep 11, 2003 at 08:03 UTC

    Good point ++dws. I tried stepping by 1 (since 130171 is prime :-/) and it worked. I came back after doing a little work solving a stupid math error on my part with this code:

    ... my $readamount = int(($length - $got_so_far)/8192)?8192:$length-$g +ot_so_far; while ( ($got_so_far < $length) and read( $sock, $buffer, $readamo +unt ) ){ print $fh $buffer; $got_so_far += length $buffer; $readamount = int(($length - $got_so_far)/8192)?8192:$length-$ +got_so_far; print "Got: $got_so_far\n" if $DEBUG; } ...

    and you had already made the points I was going to make. However, to the OP: Hope this helps.

    Update: Thanks to dws for pointing out a possible block situation. Note to the OP that the read under init_download should probably choose a smaller chunk to be read. Of course, you could also just use sysread. :)

    antirice    
    The first rule of Perl club is - use Perl
    The
    ith rule of Perl club is - follow rule i - 1 for i > 1