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

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.

Replies are listed 'Best First'.
Re^5: Read Socket on Server
by ikegami (Patriarch) on Sep 30, 2008 at 02:24 UTC

    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 $!;