P
paulmlieberman
The following code, modified from Lincoln Stein's "Network Programming
with Perl", doesn't work properly on Unix (5.6.1) or Windows systems
(5.8.6). The server receives the first message, but doesn't echo it
properly. Why?
#!/usr/bin/perl
# IOserver.pl
use strict;
use IO::Socket::INET;
use constant SIMPLE_TCP_PORT => 4001;
use constant MAX_RECV_LEN => 65536;
print "Hello, World...\n";
my $local_port = shift || SIMPLE_TCP_PORT;
my $server = IO::Socket::INET->new(Proto => 'tcp',
Type => SOCK_STREAM,
Reuse => 1,
Timeout => 60 * 60,
LocalPort => $local_port,
Listen => SOMAXCONN)
or die "Can't create server\n";
my $fromWho;
my $peeraddr;
while($fromWho = $server->accept())
{
my $hostinfo;
my $data;
$fromWho->recv($data, MAX_RECV_LEN);
if($fromWho)
{
$peeraddr = $fromWho->peeraddr();
$hostinfo = gethostbyaddr($peeraddr, AF_INET);
warn "Received from server: ", length($data), ' -> ', $data, "\n";
}
else
{
warn "IOserver: problem with recv: $!\n";
next;
}
sleep(3);
warn "Sending back to client...\n";
if (! $server->send($data, 0, $fromWho)) {
my $so_error = $server->sockopt(SO_ERROR);
die "IOserver: error $so_error sending message to $hostinfo: $!\n";
}
}
$server->close()
or warn "IOserver: close failed: $!\n";
===========================================================================
#!/usr/bin/perl
# IOclient.pl
use strict;
use IO::Socket::INET;
use constant SIMPLE_TCP_PORT => 4001;
use constant REMOTE_HOST => 'localhost';
use constant MAX_RECV_LEN => 65536;
my $remote_host = shift || REMOTE_HOST;
my $remote_port = shift || SIMPLE_TCP_PORT;
my $msg_count = 1;
my $big_chunk = 'x' x 65000;
my $client = IO::Socket::INET->new(Proto => 'tcp',
Type => SOCK_STREAM,
PeerAddr => $remote_host,
PeerPort => $remote_port)
or die "connection to remote system failed: $!\n";
while($msg_count)
{
next unless $client;
print "Enter string to echo: ";
$big_chunk = <STDIN>;
my $data = $client->sockhost() .' '. $msg_count . ' -> ' .
$big_chunk;
warn "Sending echo string to server...\n";
$client->send($data, 0)
or warn "problem with send...\n";
sleep(1);
my $fromWho = $client->recv($data, MAX_RECV_LEN, 0)
or die "Problem with recv(): $!\n";
if($fromWho)
{
my $remote_name = $client->peerhost();
warn "Received from $remote_name: ", length($data), ' => ',$data,
"\n";
}
else
{
warn "problem with recv: $!\n";
$client->close()
or warn "close failed: $!\n";
}
}
continue{
$msg_count++;
}
$client->close()
or warn "tcp_cli: close failed: $!\n";
with Perl", doesn't work properly on Unix (5.6.1) or Windows systems
(5.8.6). The server receives the first message, but doesn't echo it
properly. Why?
#!/usr/bin/perl
# IOserver.pl
use strict;
use IO::Socket::INET;
use constant SIMPLE_TCP_PORT => 4001;
use constant MAX_RECV_LEN => 65536;
print "Hello, World...\n";
my $local_port = shift || SIMPLE_TCP_PORT;
my $server = IO::Socket::INET->new(Proto => 'tcp',
Type => SOCK_STREAM,
Reuse => 1,
Timeout => 60 * 60,
LocalPort => $local_port,
Listen => SOMAXCONN)
or die "Can't create server\n";
my $fromWho;
my $peeraddr;
while($fromWho = $server->accept())
{
my $hostinfo;
my $data;
$fromWho->recv($data, MAX_RECV_LEN);
if($fromWho)
{
$peeraddr = $fromWho->peeraddr();
$hostinfo = gethostbyaddr($peeraddr, AF_INET);
warn "Received from server: ", length($data), ' -> ', $data, "\n";
}
else
{
warn "IOserver: problem with recv: $!\n";
next;
}
sleep(3);
warn "Sending back to client...\n";
if (! $server->send($data, 0, $fromWho)) {
my $so_error = $server->sockopt(SO_ERROR);
die "IOserver: error $so_error sending message to $hostinfo: $!\n";
}
}
$server->close()
or warn "IOserver: close failed: $!\n";
===========================================================================
#!/usr/bin/perl
# IOclient.pl
use strict;
use IO::Socket::INET;
use constant SIMPLE_TCP_PORT => 4001;
use constant REMOTE_HOST => 'localhost';
use constant MAX_RECV_LEN => 65536;
my $remote_host = shift || REMOTE_HOST;
my $remote_port = shift || SIMPLE_TCP_PORT;
my $msg_count = 1;
my $big_chunk = 'x' x 65000;
my $client = IO::Socket::INET->new(Proto => 'tcp',
Type => SOCK_STREAM,
PeerAddr => $remote_host,
PeerPort => $remote_port)
or die "connection to remote system failed: $!\n";
while($msg_count)
{
next unless $client;
print "Enter string to echo: ";
$big_chunk = <STDIN>;
my $data = $client->sockhost() .' '. $msg_count . ' -> ' .
$big_chunk;
warn "Sending echo string to server...\n";
$client->send($data, 0)
or warn "problem with send...\n";
sleep(1);
my $fromWho = $client->recv($data, MAX_RECV_LEN, 0)
or die "Problem with recv(): $!\n";
if($fromWho)
{
my $remote_name = $client->peerhost();
warn "Received from $remote_name: ", length($data), ' => ',$data,
"\n";
}
else
{
warn "problem with recv: $!\n";
$client->close()
or warn "close failed: $!\n";
}
}
continue{
$msg_count++;
}
$client->close()
or warn "tcp_cli: close failed: $!\n";