This is perhaps more of a general networking question than an Perl question, but I'm writing a multiplexed server using IO::Socket::INET, and I notice that some of the sockets I get back from accept() have no peer host. Here's the framework:
#!/usr/bin/perl
# Pragma
use strict;
use Carp qw(cluck);
use IO::Socket;
use IO::Select;
# Default port(s) on which to listen
our @PORTS = qw(1234 1235 1236);
# Setup IO::Select objects to manage the sockets.
our $LISTENERS = IO::Select->new() or die "IO::Select";
our $CLIENTS = IO::Select->new() or die "IO::Select";
# Open our listening ports
foreach my $port (@PORTS)
{
my $listen_socket = IO::Socket::INET->new(
LocalPort => $port,
Listen => 20,
Proto => 'tcp',
Reuse => 1
);
die "Bind failed for port $port: $@" unless $listen_socket;
$LISTENERS->add($listen_socket);
}
print "Waiting for connections\n";
while (1)
{
# Look for incoming connections
my @ready = $LISTENERS->can_read(1);
foreach my $socket (@ready)
{
my $connect = $socket->accept();
if ($connect)
{
if (!$connect->peerhost())
{
cluck("NULL PEERHOST: " . join(" : ",
$connect->sockhost(),
$connect->sockport(),
$connect->peerhost(),
$connect->peerport(),
$!
));
close($connect);
next;
}
print "Connection from ",
$connect->peerhost(),
" on port ",
$connect->sockport(),
"\n";
$CLIENTS->add($connect);
}
}
@ready = $CLIENTS->can_read(1);
foreach my $socket (@ready)
{
my $input;
my $bytes = sysread($socket, $input, 1024);
if ($bytes)
{
print "Read from client: $input";
}
else
{
print "Disconnect from ", $socket->peerhost(),
" on port ", $socket->sockport(),
"\n";
$CLIENTS->remove($socket);
close($socket);
}
}
}
The question I have is related to that cluck(). Sometimes accept() returns an IO::Socket object, but it has no peerhost. The script output looks like this:
NULL PEERHOST: X.X.X.X : 1234 : : : Transport endpoint is not connected at ./foo.pl line 45
What causes that?