Sockets: receiving data

Discussion in 'Perl Misc' started by Bigus, May 21, 2004.

  1. Bigus

    Bigus Guest

    In the program below (Thomas - you may be interested in this - as I've
    finally got out of the blocking scenario! :) I can connect and receive data
    from a mailing list system's command interpretter.

    However, I do not get back ALL the data that the mailing list system wants
    to send me. That is, in the initial binary part of the reply I get back from
    the server it indicates that there are, eg: 80,000 bytes to send me, but I
    only get back 16KB (this figure varies) before the data cuts off and the
    program stops running.

    Is there some sort of default limit at work in the socket module that is
    causing this, or is it something completely different? (this is my first
    foray into sockets, so forgive me if I'm missing some fundamental thing
    about how sockets work).

    Thanks
    Bigus

    Here's the code ->

    ==== code follows ====

    use strict;
    use warnings;
    my $email = ''
    my $cmd = "review LISTNAME msg pw=password";

    # --- Connect to Listserv --- #

    use IO::Socket;
    my $lsv = IO::Socket::INET->new(
    Proto => "tcp",
    PeerAddr => "localhost",
    PeerPort => '2306')
    or die print "Connection problem :$!";

    # --- Send Command --- #

    # form binary part of command header
    my $len = length($email)+length($cmd)+1;
    my $bin =
    pack("a*CCCa*","\r\n",int($len/256),$len-(int($len/256)*256),length($email),
    $email);

    # send command header
    print $lsv "1B".$bin;
    recv($lsv, my $ans, 100, 0);
    if($ans !~ /^250/){print "Failed because $ans\n"; exit;}

    # followed by command itself
    print $lsv "$cmd\n";

    # --- Get Reply --- #

    # get binary part of reply & decode
    recv($lsv, $ans, 8, 0);
    my @an = $ans =~ /.{4}/g;
    my $rcode = unpack("N",$an[0]);
    my $rlen = unpack("N",$an[1]);
    if($rcode != 0){print "Failed on $rcode (len $rlen)\n"; exit;}

    # and get reply itself
    recv($lsv, my $reply, $rlen, 0);
    print "$reply\n\nHeader: $rcode - $rlen";

    # --- Close Socket --- #

    close $lsv;
     
    Bigus, May 21, 2004
    #1
    1. Advertising

  2. "Bigus" <> wrote in
    news:c8ksh0$:

    > In the program below (Thomas - you may be interested in this - as I've
    > finally got out of the blocking scenario! :) I can connect and
    > receive data from a mailing list system's command interpretter.
    >
    > However, I do not get back ALL the data that the mailing list system
    > wants to send me. That is, in the initial binary part of the reply I
    > get back from the server it indicates that there are, eg: 80,000 bytes
    > to send me, but I only get back 16KB (this figure varies) before the
    > data cuts off and the program stops running.
    >
    > Is there some sort of default limit at work in the socket module that
    > is causing this, or is it something completely different? (this is my
    > first foray into sockets, so forgive me if I'm missing some
    > fundamental thing about how sockets work).



    > use strict;
    > use warnings;


    Good.

    > my $email = ''


    Missing semi-colon at the end of the line above. Is this the code you
    actually ran?

    > my $cmd = "review LISTNAME msg pw=password";
    >
    > # --- Connect to Listserv --- #
    >
    > use IO::Socket;
    > my $lsv = IO::Socket::INET->new(
    > Proto => "tcp",
    > PeerAddr => "localhost",
    > PeerPort => '2306')
    > or die print "Connection problem :$!";


    You create a TCP socket here.
    ....

    > # send command header
    > print $lsv "1B".$bin;
    > recv($lsv, my $ans, 100, 0);
    > if($ans !~ /^250/){print "Failed because $ans\n"; exit;}


    recv is for UDP.


    --
    A. Sinan Unur
    (reverse each component for email address)
     
    A. Sinan Unur, May 21, 2004
    #2
    1. Advertising

  3. Bigus

    Bigus Guest

    > > my $email = ''
    >
    > Missing semi-colon at the end of the line above. Is this the code you
    > actually ran?


    No.. I had to change that line when copying it into the post, lest I be
    spammed to eternity.

    > > my $cmd = "review LISTNAME msg pw=password";
    > >
    > > # --- Connect to Listserv --- #
    > >
    > > use IO::Socket;
    > > my $lsv = IO::Socket::INET->new(
    > > Proto => "tcp",
    > > PeerAddr => "localhost",
    > > PeerPort => '2306')
    > > or die print "Connection problem :$!";

    >
    > You create a TCP socket here.
    > ...
    >
    > > # send command header
    > > print $lsv "1B".$bin;
    > > recv($lsv, my $ans, 100, 0);
    > > if($ans !~ /^250/){print "Failed because $ans\n"; exit;}

    >
    > recv is for UDP.


    Oh. Sounds kind of fudnamental.. it works for smaller amounts of data
    though. The main reason I am using that is because there's an example script
    in C that does what I'm trying to do here. I don't understand half of it,
    but it does use the recv command and is definitely over TCP, since the
    interface is called TCPGUI. Maybe C is different in the way it handles
    sockets or something.

    Is there a quick-fix TCP alternative to recv in this context, or am I going
    to have to do a loop again and get into a loop again and revisit the block
    scenario?

    Thanks
    Bigus
     
    Bigus, May 21, 2004
    #3
  4. Bigus

    Bigus Guest

    > > recv is for UDP.
    >
    > Oh. Sounds kind of fudnamental.. it works for smaller amounts of data
    > though. The main reason I am using that is because there's an example

    script
    > in C that does what I'm trying to do here. I don't understand half of it,
    > but it does use the recv command and is definitely over TCP, since the
    > interface is called TCPGUI. Maybe C is different in the way it handles
    > sockets or something.
    >
    > Is there a quick-fix TCP alternative to recv in this context, or am I

    going
    > to have to do a loop again and get into a loop again and revisit the block
    > scenario?


    OK. got it:

    Read()

    and it works a treat (maybe I should add "so far" just in case I come across
    another stumbling block)

    :)

    Regards
    Bigus
     
    Bigus, May 21, 2004
    #4
  5. "Bigus" <> wrote in
    news:c8l044$:

    >> > recv is for UDP.

    >>
    >> Oh. Sounds kind of fudnamental.. it works for smaller amounts of data
    >> though. The main reason I am using that is because there's an example
    >> script in C that does what I'm trying to do here. I don't understand
    >> half of it, but it does use the recv command and is definitely over
    >> TCP, since the interface is called TCPGUI. Maybe C is different in the
    >> way it handles sockets or something.


    TCPGUI seems to be a library for your platform.

    >>
    >> Is there a quick-fix TCP alternative to recv in this context, or am I
    >> going to have to do a loop again and get into a loop again and revisit
    >> the block scenario?

    >
    > OK. got it:
    >
    > Read()
    >
    > and it works a treat (maybe I should add "so far" just in case I come
    > across another stumbling block)
    >
    >:)


    I am not a TCP/IP or sockets expert by any means. I have written a few
    programs in C (Winsock), Java, and Perl that use sockets. So my humble
    advice to you is to read some generic sockets related literature first.

    --
    A. Sinan Unur
    (reverse each component for email address)
     
    A. Sinan Unur, May 21, 2004
    #5
  6. Bigus

    Ben Morrow Guest

    Quoth Jim Gibson <>:
    > Stick to the object-oriented versions of the socket functions. E.g.,
    > use $lsv->recv(...) instead of recv(...) (although as you have
    > discovered you should be using read instead of recv). You are calling
    > the basic Perl recv function with a reference to an IO::Socket::INET
    > object instead of a file handle as the first argument. That may or may
    > not work.


    An IO::Socket::INET ISA IO::Handle which is a filehandle. (To be more
    specific, an IO::Handle is a blessed globref.) It works just fine.

    Ben

    --
    If I were a butterfly I'd live for a day, / I would be free, just blowing away.
    This cruel country has driven me down / Teased me and lied, teased me and lied.
    I've only sad stories to tell to this town: / My dreams have withered and died.
    (Kate Rusby)
     
    Ben Morrow, May 22, 2004
    #6
  7. Bigus

    Bigus Guest

    "Jim Gibson" <> wrote in message
    news:210520041329166224%...
    > In article <c8kurh$>, Bigus
    > <> wrote:
    >
    > > > > my $email = ''
    > > >
    > > > Missing semi-colon at the end of the line above. Is this the code you
    > > > actually ran?

    > >
    > > No.. I had to change that line when copying it into the post, lest I be
    > > spammed to eternity.
    > >
    > > > > my $cmd = "review LISTNAME msg pw=password";
    > > > >
    > > > > # --- Connect to Listserv --- #
    > > > >
    > > > > use IO::Socket;
    > > > > my $lsv = IO::Socket::INET->new(
    > > > > Proto => "tcp",
    > > > > PeerAddr => "localhost",
    > > > > PeerPort => '2306')
    > > > > or die print "Connection problem :$!";
    > > >
    > > > You create a TCP socket here.
    > > > ...
    > > >
    > > > > # send command header
    > > > > print $lsv "1B".$bin;
    > > > > recv($lsv, my $ans, 100, 0);
    > > > > if($ans !~ /^250/){print "Failed because $ans\n"; exit;}
    > > >
    > > > recv is for UDP.

    > >
    > > Oh. Sounds kind of fudnamental.. it works for smaller amounts of data
    > > though. The main reason I am using that is because there's an example

    script
    > > in C that does what I'm trying to do here. I don't understand half of

    it,
    > > but it does use the recv command and is definitely over TCP, since the
    > > interface is called TCPGUI. Maybe C is different in the way it handles
    > > sockets or something.

    >
    > Perl calls the socket functions in the C library for your platform, so
    > the behavior should be the same. Perl recv calls C recvfrom, and is
    > definitely a UDP function.
    >
    > Stick to the object-oriented versions of the socket functions. E.g.,
    > use $lsv->recv(...) instead of recv(...) (although as you have
    > discovered you should be using read instead of recv). You are calling
    > the basic Perl recv function with a reference to an IO::Socket::INET
    > object instead of a file handle as the first argument. That may or may
    > not work.


    OK, I've done that now. What's the advantage of referencing the object when
    calling a function? Is it something to do with error-trapping?

    Thanks
    Bigus
     
    Bigus, May 22, 2004
    #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. fredd00
    Replies:
    0
    Views:
    299
    fredd00
    May 31, 2007
  2. fredd00
    Replies:
    0
    Views:
    343
    fredd00
    May 31, 2007
  3. fredd00
    Replies:
    0
    Views:
    339
    fredd00
    Jun 1, 2007
  4. Johnny Venter

    Fwd: Sockets: Receiving C Struct

    Johnny Venter, Aug 5, 2011, in forum: Python
    Replies:
    0
    Views:
    150
    Johnny Venter
    Aug 5, 2011
  5. Johnny Venter

    Sockets: Receiving C Struct

    Johnny Venter, Aug 5, 2011, in forum: Python
    Replies:
    0
    Views:
    157
    Johnny Venter
    Aug 5, 2011
Loading...

Share This Page