Sockets: receiving data

B

Bigus

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 = '(e-mail address removed)'
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;
 
A

A. Sinan Unur

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 = '(e-mail address removed)'

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

Bigus

my $email = '(e-mail address removed)'
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.
You create a TCP socket here.
...


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
 
B

Bigus

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
 
A

A. Sinan Unur

TCPGUI seems to be a library for your platform.
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.
 
B

Ben Morrow

Quoth Jim Gibson said:
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
 
B

Bigus

Jim Gibson said:
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
 

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,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top