sample client server socket issue

Discussion in 'Perl Misc' started by jm, Mar 6, 2008.

  1. jm

    jm Guest

    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.
    jm, Mar 6, 2008
    #1
    1. Advertising

  2. jm

    Ben Morrow Guest

    Quoth 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.


    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
    Ben Morrow, Mar 6, 2008
    #2
    1. Advertising

  3. jm

    jm Guest

    Ben Morrow a écrit :
    > Quoth 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.


    > 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!
    jm, Mar 6, 2008
    #3
  4. jm

    Guest

    Ben Morrow <> wrote:
    > Quoth jm <>:

    ....
    > > 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,


    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.
    , Mar 6, 2008
    #4
  5. jm

    Ben Morrow Guest

    Quoth :
    > Ben Morrow <> wrote:
    > > Quoth jm <>:

    > ...
    > > > 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,

    >
    > 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
    Ben Morrow, Mar 7, 2008
    #5
  6. jm

    jm Guest

    Jim Gibson a écrit :
    > In article <47d071a9$0$21144$-internet.fr>, jm
    > <> wrote:
    >
    >> 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 ;
    >> }

    >
    > 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.
    jm, Mar 7, 2008
    #6
  7. jm

    Ben Morrow Guest

    Quoth jm <>:
    >
    > 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
    Ben Morrow, Mar 8, 2008
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Avizz
    Replies:
    3
    Views:
    13,749
    Andy Fish
    Sep 29, 2003
  2. greatestmclarenfan
    Replies:
    2
    Views:
    564
    Steve Horsley
    Feb 16, 2006
  3. Laszlo Nagy
    Replies:
    1
    Views:
    4,755
    Mark Wooding
    Jan 27, 2009
  4. Jean-Paul Calderone
    Replies:
    0
    Views:
    942
    Jean-Paul Calderone
    Jan 27, 2009
  5. Laszlo Nagy
    Replies:
    0
    Views:
    524
    Laszlo Nagy
    Feb 1, 2009
Loading...

Share This Page