server.pl
sub sock_initialize {
my $sock = q{};
my $port = q{};
# Get a port for our server.
$sock = IO::Socket::INET->new(
Listen => SOMAXCONN, # listen queue depth
LocalPort => 0,
Reuse => 1
);
die "Unable to bind a port: $!" if !$sock;
$port = $sock->sockport();
my $ip = "";
my $uid = (getpwuid( $> ))[2];
my $queue = join(":", $ip, $port, $$, $uid);
print sprintf("put started on port $port ($$), SOMAXCONN=%d\n", SOMAXCONN);
return $sock;
} ## end sub sock_initialize
my $listen_sock = sock_initialize();
while (1) {
#my $xsock = Accept();
my $xsock;
while (1) {
$! = 0;
# Accept can block. Need to use nonblocking poll (Stevens)
$xsock = $listen_sock->accept; # ACCEPT
last if defined $xsock;
next if $! == EINTR;
die "accept error: $!";
if ( defined $xsock ) {
$xsock->blocking(0); # mark executor socket nonblocking
$xsock->sockopt( SO_KEEPALIVE() => 1 ) or die "sockopt: $!";
}
#my $rbufp = $conn->readbufref;
#my $rdstatus = Read( $sock, $rbufp );
my $buff = "";
while (1) {
$! = 0;
# Accept can block. Need to use nonblocking poll (Stevens)
$xsock = $listen_sock->accept; # ACCEPT
last if defined $xsock;
next if $! == EINTR;
die "accept error: $!";
if ( defined $xsock ) {
$xsock->blocking(0); # mark executor socket nonblocking
$xsock->sockopt( SO_KEEPALIVE() => 1 ) or die "sockopt: $!";
}
}
#my $rbufp = $conn->readbufref;
#my $rdstatus = Read( $sock, $rbufp );
my $buff = "";
while (1) {
my $nbytes = sysread $xsock, $buff, 32768, length($buff); # SYSCALL
if ( !defined $nbytes ) { # read error
next if $! == EINTR;
last if $! == EWOULDBLOCK; # normal
return;
}
last if $nbytes == 0; # EOF
}
print "received $buff\n";
last;
}
client.pl
my $host = "localhost";
my $port = 37402; # get port number from server.pl
my $s = IO::Socket::INET->new (PeerAddr => $host,
PeerPort => $port,
Type => SOCK_STREAM,
Proto => 'tcp',
Timeout => 1);
if ($s) {
$s->blocking (0) ;
}
my $nbytes = syswrite $s, "hi from X"; # SYSCALL
First, i would start server.pl
$perl test_socket_server.pl
$put started on port 37402 (16974), SOMAXCONN=128
Then i would put the port number on client.pl
perl test_socket_client.pl
then, on server.pl shell, i see
received hi from X
So, it's working as intended. Now when I put the server.pl inside a container via
docker run ubuntu perl server.pl
put started on port 38170 (1), SOMAXCONN=128
And then, I would write the port number in client.pl and run it, but server.pl does not get the message
My understanding is that container port isnt expose to host's via EXPOSE
Now, even if the problem could be fixed with EXPOSE, server.pl connects on an unassigned port i.e the pornumber can change every time it runs LocalPort => 0,
server.pl is run inside the container. My understanding is you have to expose the port at container runtime but at this time, you dont know which port server.pl will run at. And I would like it to be this way, no designated port, as multiple instances of server.pl could be run in a container (so need to be able to use different ports). Is there a strategy to accommodate this?
can you expose port ranges, perhaps, 30000 and upwards when starting container? [I've read some other stack overflow questions on exposing port ranges but it seems to have some performance issues as a real process is forked per port (?) Docker expose all ports or range of ports from 7000 to 8000 The ideal solution would be somehow only exposing ports being used by the app which resides in a container at runtime. Maybe that is accomplished by an orchestrator?