adamsj has asked for the wisdom of the Perl Monks concerning the following question:
Stein gives code, which I followed fairly closely, for echo clients and servers, each implemented once with Socket and once with IO::Socket. The Socket implementations worked fine. Then I tried the IO::Socket client implementation, which worked fine against the Socket server. However, neither client worked against the IO::Socket implementation--it looks like a deadlock condition. Finally, just for grins, I telneted directly to the server, and lost the deadlock--the text came right back.
I'm finding this pretty puzzling--I've tried various things, including explicitly setting autoflush on (yes, I know it's on be default, but wotthehell). I'm not getting any success. Any thoughts? I'm using current versions from ActiveState Build 628 on Windows ME. Code snippets follow:
my $protocol = getprotobyname('tcp'); socket(SOCK, AF_INET, SOCK_STREAM, $protocol) or die "No socket: $!"; setsockopt(SOCK, SOL_SOCKET, SO_REUSEADDR, 1) or die "No SO_REUSEADDR: + $!"; my $my_addr = sockaddr_in($port, INADDR_ANY); bind(SOCK, $my_addr) or die "No bind: $!"; listen(SOCK,SOMAXCONN) or die "No listen: $!"; warn "listening on port $port...\n"; while ( 1 ) { next unless my $remote_addr = accept(SESSION, SOCK); my ($port, $hisaddr) = sockaddr_in($remote_addr); warn "Connection from [",inet_ntoa($hisaddr),",$port]\n"; SESSION->autoflush(1); while(<SESSION>) { $bytes{'in'} += length($_); chomp; my $msg_out = scalar reverse $_ . "\n"; print SESSION $msg_out; $bytes{'out'} += length($msg_out); } warn "Connection from [",inet_ntoa($hisaddr),",$port] finished\n"; close SESSION; } close SOCK;
This works fine. Now, here's the IO::Socket server code:
my $socket = IO::Socket::INET->new( Listen => 20, LocalPort => $port, Timeout => 5, #60 * 60, Reuse => 1) or die "No socket: $!"; warn "listening on port $port...\n"; while ( !$quit ) { next unless my $session = $socket->accept; my $peer = gethostbyaddr($session->peeraddr,AF_INET) || $session->peerhost; my $port = $session->peerport; warn "Connection from [$peer,$port]\n"; while(<$session>) { #BLOCKS HERE $bytes{'in'} += length($_); chomp; my $msg_out = $_ . CRLF; $session->print($msg_out); print $msg_out; $bytes{'out'} += length($msg_out); } warn "Connection from [$peer,$port] finished\n"; close $session; }
Here's some of the client code, Socket version:
my $socket = IO::Socket::INET->new("$host:$port") or die "No connect: +$!"; my $protocol = getprotobyname('tcp'); my $ok = 1; $socket->autoflush(1); while ( defined (my $msg_out = STDIN->getline) ) { last unless $ok; print $socket $msg_out; my $msg_in = <$socket>; print $msg_in; $bytes{'out'} += length($msg_out); $bytes{'in'} += length($msg_in); }
They laughed at Joan of Arc, but she went right ahead and built it. --Gracie Allen
Edited 2001-08-12 by Ovid.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: IO::Socket vs. Socket vs. of-the-shelf telnet
by abstracts (Hermit) on Aug 12, 2001 at 22:56 UTC | |
by adamsj (Hermit) on Aug 13, 2001 at 00:13 UTC | |
by abstracts (Hermit) on Aug 13, 2001 at 00:36 UTC | |
Re: IO::Socket vs. Socket vs. off-the-shelf telnet
by dga (Hermit) on Aug 13, 2001 at 07:57 UTC | |
by abstracts (Hermit) on Aug 13, 2001 at 20:56 UTC |