sample client server socket issue

J

jm

I have written some perl client program and javascript server program.

Communication seams working in both direction, but the perl client
cannot read final data.

Perl use socket in blocking mode (default).
I open the connection with localhost, port number, and tcp.


When I read packets with a size of 512 or 4096, everything works fine
till the last packet. As the last packet is smaller than 4096, perl stay
blocked waiting for a complete packet.

I just want it to be blocked when no byte is available.

When I do not use a size of 512 or 4096, but a size of 1, everything
works fine, but I am wondering if it will not be too much slow.

my $buffer = '';
while ( not $buffer =~ /\n\n/ )
{
my $packet;
sysread $sock, $packet, 4096 ;
$buffer .= $packet ;
}



NB: I have tried different technics to read data:
$sock->read
$sock->recv
sysread $sock
and so on. This does not solve the problem.
 
B

Ben Morrow

Quoth jm said:
I have written some perl client program and javascript server program.

Communication seams working in both direction, but the perl client
cannot read final data.

Perl use socket in blocking mode (default).
I open the connection with localhost, port number, and tcp.

When I read packets with a size of 512 or 4096, everything works fine
till the last packet. As the last packet is smaller than 4096, perl stay
blocked waiting for a complete packet.

When you say 'last packet', do you mean 'last packet before the
connection is closed' or 'last packet in this request'? If you mean the
former, then Perl will return an incomplete packet even in blocking
mode. If the latter, then you need to set the socket to non-blocking
mode, and be prepared to handle short reads all the way through. You
will also need to use IO::Select to wait for data after you get a short
read.

Ben
 
J

jm

Ben Morrow a écrit :
When you say 'last packet', do you mean 'last packet before the
connection is closed' or 'last packet in this request'?

I mean the server send several lines of text, then an empty line.
Then the server wait for the client.

All theses lines of text are assembled by network stacks in buffers of
4096 bytes, but last characters wont.


If you mean the
former, then Perl will return an incomplete packet even in blocking
mode.

If the latter, then you need to set the socket to non-blocking
mode, and be prepared to handle short reads all the way through. You
will also need to use IO::Select to wait for data after you get a short
read.

Ben

I was believing blocking mode better than non blocking!
 
X

xhoster

Ben Morrow said:
Quoth jm <[email protected]>: ....

When you say 'last packet', do you mean 'last packet before the
connection is closed' or 'last packet in this request'? If you mean the
former, then Perl will return an incomplete packet even in blocking
mode. If the latter, then you need to set the socket to non-blocking
mode,

I have never seen this behavior with sysread. The only time I've seen
sysread block is when the alternative is to read 0 bytes (and of course
not even then when set to non-blocking). It happily does short non-zero
length reads when the alternative is blocking, even without setting it to
non-blocking mode.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
B

Ben Morrow

Quoth (e-mail address removed):
I have never seen this behavior with sysread. The only time I've seen
sysread block is when the alternative is to read 0 bytes (and of course
not even then when set to non-blocking). It happily does short non-zero
length reads when the alternative is blocking, even without setting it to
non-blocking mode.

Yes, you would seem to be correct, at least here (FreeBSD). I don't know
what's going on for the OP, then.

Ben
 
J

jm

Jim Gibson a écrit :
How do you know the problem is not with your server? We can't tell,
since you have not shown us your code. You should 1) capture the return
value of sysread and check it for a) the number of bytes read, b) a 0
if the socket has been closed, or c) undef if an error has occurred,
and 2) print the return value and the bytes read, if any.


When debugging the code, I had replaced sysread, by recv and read methods.

I moved back to the sysread, and it looks like working fine.

However, I am not sure documentation clearly explain why $sock->send for
sending, and why sysread for reading...

thanks.
 
B

Ben Morrow

Quoth jm said:
When debugging the code, I had replaced sysread, by recv and read methods.

I moved back to the sysread, and it looks like working fine.

However, I am not sure documentation clearly explain why $sock->send for
sending, and why sysread for reading...

$sock->send with at most two arguments (plus $sock itself) ends up
calling send(2), which (under Unix, at any rate) is exactly equivalent
to write(2), which is what syswrite calls. $sock->send with three
arguments calls sendto(2), which is quite different; also, I believe
there are operating systems where send(2) and write(2) are different,
though I think perl deals with that for you if it needs to.

The same applies to recv/sysread. Perl's read, however, calls fread(3),
(or rather PerlIO's equivalent) which is buffered. Buffered reads do
behave exactly as you described: they will wait for ever (or until EOF,
or error) for a full buffer if the underlying file descriptor is in
blocking mode. So don't do that: stick to sysread or recv.

Alternatively, if you're using 5.8 you can push a :unix layer

binmode $sock, ':unix';

which will let you use <> and so on in unbuffered mode. It probably
isn't as efficient as doing your own buffering, but it's a lot more
convenient.

Ben
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top