#SERVER: use strict; use warnings; use 5.010; use Socket; my $protocol = getprotobyname 'tcp'; socket my $LISTEN_SOCK, AF_INET, SOCK_STREAM, $protocol or die "Can't make socket: $!"; setsockopt $LISTEN_SOCK, SOL_SOCKET, SO_REUSEADDR, 1 or die "Cant set SO_REUSADDR: $!"; my $port = 12555; my $listen_addr = sockaddr_in $port, INADDR_ANY; bind $LISTEN_SOCK, $listen_addr or die "bind failed: $!"; listen $LISTEN_SOCK, 5; warn "processing sockets...\n"; my $rin = ''; my $rout; vec($rin, fileno($LISTEN_SOCK), 1) = 1; my %open_sockets; my ($remote_host, $remote_port); while (1) { my $nfound = select ($rout=$rin, undef, undef, undef); if ($nfound) { if (vec $rout, fileno $LISTEN_SOCK, 1) { my $packed_remote_addr = accept my ($CONNECTION), $LISTEN_SOCK; if ($packed_remote_addr) { vec($rin, fileno $CONNECTION, 1) = 1; ($remote_port, my $packed_remote_host) = unpack_sockaddr_in($packed_remote_addr); $remote_host = inet_ntoa $packed_remote_host; warn "adding new connection to hash...\n"; $open_sockets{fileno $CONNECTION} = [$CONNECTION, "$remote_host : $remote_port"]; } else { warn "couldn't connect"; } } for my $filenum (keys %open_sockets) { my ($CONN, $remote_info) = @{$open_sockets{$filenum}}; if (vec $rout, $filenum, 1) { my $available_data; my $result = sysread $CONN, $available_data, 8096; if ($result) { #data was read from socket print "[$remote_info] says: $available_data"; } elsif ($result == 0) { #eof=>socket closed delete $open_sockets{$filenum}; vec($rin, $filenum, 1) = 0; close $CONN; say "[$remote_info]: deleted from hash. Goodbye!"; } else {#undef=>IO error on socket warn "[$remote_info]: experienced an IO error: $!"; } } } } }