in reply to Re^2: Read Socket on Server
in thread Read Socket on Server

Do you actually get the output you describe from the posted version or only the non-blocking version? Something is seriously messed up to get the behaviour you described from the code you posted. It makes more sense for the non-blocking version since you never clear $data.

Update: To clarify, by "you never clear $data", I mean you rely on sysread to clear $data, and it's entirely reasonable to fit to not do so when it detects there's nothing to read.

Replies are listed 'Best First'.
Re^4: Read Socket on Server
by ipentinmaki (Initiate) on Sep 30, 2008 at 01:53 UTC
    Your right I made an assumption about sysread clearing the data in the example.
    Clearing $data and $rc inbetween had no effect.
    Yes, both the blocking short example and the non-blocking full version are behaving the same way on windows as the sysread result is greater than zero.
    I checked the simple client and larger version on HP-UX with the same behavior. I also added enough code to the example to send an ack back so I don't think it is a resend.

      That's not how it should behave, and I cannot replicate your results (ActivePerl 5.8.8 on WinXP).

      sysread blocks until the server sends data, and which point the data is returned in $data, overwriting what's already there.

      The only reason you'd get the same data repeatedly was if the server was sending it repeatedly.

      For testing, I used

      #!/usr/local/bin/perl # client.pl use strict; use Socket; use Time::HiRes qw( sleep ); use IO::Handle; my $prot = getprotobyname('tcp'); my $host = inet_aton("localhost"); socket(SOCK, AF_INET, SOCK_STREAM, $prot) or die("socket failed to sta +rt"); my $dest_addr = sockaddr_in(5003, $host); connect(SOCK, $dest_addr) or die("Connect failed"); my $data = 'aaaaaaaaaaaaaaaaaaaaaaaa'; while (1) { print STDERR "do a read\n"; sysread(SOCK, $data, 1024); # reads the data on the serve +rs socket # but when loop around again +the data is still there as server # has not written anything ne +w print STDERR "data was $data\n"; sleep(0.2); } close SOCK;
      #!/usr/bin/perl # server.pl use strict; use warnings; use IO::Socket::INET; my $sock = IO::Socket::INET->new( Proto => 'tcp', LocalPort => 5003, Listen => 1, ) or die; my $client = $sock->accept() or die; for (;;) { my $x = sprintf( '%04d', rand(1000) ); print( "$x\n" ); print $client ( $x ) or last; sleep(1); }

      By the way,

      use IO::Handle; my $prot = getprotobyname('tcp'); my $host = inet_aton("localhost"); socket(SOCK, AF_INET, SOCK_STREAM, $prot) or die("socket failed to sta +rt"); my $dest_addr = sockaddr_in(5003, $host); connect(SOCK, $dest_addr) or die("Connect failed");

      is much more readable as

      use IO::Socket::INET; my $sock = IO::Socket::INET->new( Proto => 'tcp', PeerAddr => 'localhost', PeerPort => 5003, ) or die $!;