Buffered socket I/O with sysread-style blocking?

C

Charles DeRykus

James said:
...
That's probably what I'll end up doing, but I don't think the switch is
so simple (is it?). I also might try to read one HTML tag at a time
using <> with $/=='>', though that has pitfalls and is somewhat
inefficient.

Parsing the tags would be lots easier with HTML::parser, which like the
suggested LWP::parallel for making the requests, enables you to specify
a callback to process data as it arrives.

hth,
 
X

xhoster

Uri Guttman said:
x> Right, but they are only semi-nonblocking (and the semi part of it
x> is not in the way the OP wants, or thinks we wants.)

semi-nonblocking? huh??

Yeah. You don't block on the <> while waiting for a message to start,
because using select you know not to call <> until at least one character
(or eof) has been sent. But once at least one character has been sent and
you do call <>, then you do block until $/ is received. You don't block
waiting for the start of a message, but you do block waiting for the end
of it. The OP wants to do the opposite.
x> <> isn't the only thing he uses, he also uses read, which does not
x> work well in a select loop. And <> doesn't mix with O_NONBLOCK.

<> doesn't mix with sysread. you can do nonblocking i/o with <> but it
makes little sense.

The reason is makes little sense is because it doesn't work the way you
think it does. If it did work like you say, then it would sometimes make
sense to use it that way.
<> will read until it hits a newline, blocking or
not. it just keeps in a read loop.

No it doesn't. Under non-blocking, it returns with whatever chunk
of string it happens to get handed, whether it is terminated by $/
(or eof condition) or not.
so the non-blocking shouldn't even
affect <> (but i am not going to test it).

I will.

$ cat server.pl
#!/usr/bin/perl -wl
use strict;
use IO::Socket;
use IO::Handle;
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
my $remote = IO::Socket::INET->new(
Proto=>"tcp",LocalPort=>9001,Listen=>1,Reuse=>SO_REUSEADDR,
) or die $!;
while (my $connect =$remote->accept) {
print $connect;
my $flags = fcntl($connect, F_GETFL, 0) or die $!;
$flags = fcntl($connect, F_SETFL, $flags | O_NONBLOCK) or die $!;
WHILE: while (1) {
$!=0;
my $foo = <$connect>;
print "Read ", length ($foo||''), " bytes with $!";
sleep 1 unless defined $foo;
};
};
__END__
IO::Socket::INET=GLOB(0x663570)
Read 0 bytes with Resource temporarily unavailable
Read 165456 bytes with Resource temporarily unavailable
Read 0 bytes with Resource temporarily unavailable
Read 200768 bytes with Resource temporarily unavailable
Read 0 bytes with Resource temporarily unavailable
Read 201000 bytes with Resource temporarily unavailable
Read 0 bytes with Resource temporarily unavailable
Read 201000 bytes with Resource temporarily unavailable
Read 0 bytes with Resource temporarily unavailable
Read 201000 bytes with Resource temporarily unavailable
Read 0 bytes with Resource temporarily unavailable
.....

Driven by
perl -e 'use IO::Socket; my $s=new IO::Socket::INET("localhost:9001") or \
die $@; print $s "foo"x1000 foreach 1..1000; print $s "\n"'

If you don't set O_NONBLOCK, then you get one read of 3_000_001 characters,
rather than all of those partial, non $/ terminated reads.

the blocking nature of a
socket has nothing to do with buffering or how you read it. the mixing
of read methods (buffered <> vs unbuffered sysread) is the big no-no as
a sysread after <> may not see any data already read by <> and which is
sitting in the stdin buffers.

And a select after a <> may also not see any data already read by <>
which is sitting in the buffer. Usually, this only leads to inefficiency
(Not seeing a message until another message has arrived after it, or eof)
rather than outright errors, but it can cause deadlocks.

Xho
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top