You want to write a server that waits for clients to connect over the network to a particular port.
This recipe assumes you're using the Internet to communicate. For TCP-like communication within a single Unix machine, see Recipe 17.6 .
Use the standard (as of 5.004) IO::Socket::INET class:
use IO::Socket; $server = IO::Socket::INET->new(LocalPort => $server_port, Type => SOCK_STREAM, Reuse => 1, Listen => 10 ) # or SOMAXCONN or die "Couldn't be a tcp server on port $server_port : $@\n"; while ($client = $server->accept()) { # $client is the new connection } close($server);
Or, craft it by hand for better control:
use Socket; # make the socket socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp')); # so we can restart our server quickly setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1); # build up my socket address $my_addr = sockaddr_in($server_port, INADDR_ANY); bind(SERVER, $my_addr) or die "Couldn't bind to port $server_port : $!\n"; # establish a queue for incoming connections listen(SERVER, SOMAXCONN) or die "Couldn't listen on port $server_port : $!\n"; # accept and process connections while (accept(CLIENT, SERVER)) { # do something with CLIENT } close(SERVER);
Setting up a server is more complicated than being a client. The optional
listen
function tells the operating system how many pending, unanswered connections to queue up waiting for your server. The
setsockopt
function used in the Solution allows you to avoid waiting two minutes after killing your server before you restart it again (valuable in testing). The
bind
call registers your server with kernel so others may find you. Finally,
accept
takes the incoming connections one by one.
The numeric argument to
listen
is the number of un
accept
ed connections that the operating system should queue before clients start getting "connection refused" errors. Historically, the maximum
listen
value was 5, and even today, many operating systems silently limit this queue size to around 20. With busy web servers becoming commonplace, many vendors have increased this value. Your documented system maximum can be found in the SOMAXCONN constant from the Socket module.
The
accept
function takes two arguments: the filehandle to connect to the remote client and the server filehandle. It returns the client's port and IP address, as packed by
inet_ntoa
:
use Socket; while ($client_address = accept(CLIENT, SERVER)) { ($port, $packed_ip) = sockaddr_in($client_address); $dotted_quad = inet_ntoa($packed_ip); # do as thou wilt }
With the IO::Socket classes,
accept
is a method of the server filehandle:
while ($client = $server->accept()) { # ... }
If you call the
accept
method in list context, it returns the client socket and its address:
while (($client,$client_address) = $server->accept()) { # ... }
If no connection is waiting, your program blocks in the
accept
until a connection comes in. If you want to ensure that your
accept
won't block, use
non-blocking sockets:
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); $flags = fcntl(SERVER, F_GETFL, 0) or die "Can't get flags for the socket: $!\n"; $flags = fcntl(SERVER, F_SETFL, $flags | O_NONBLOCK) or die "Can't set flags for the socket: $!\n";
Now, when you
accept
and nothing is waiting for you,
accept
will return
undef
and set
$!
to
EWOULDBLOCK
.
You might fear that when the return flags from F_GETFL are 0, that this would trigger the
die
just as a failure from
undef
would. Not so - as with
ioctl
, a non-error return from
fcntl
is mapped by Perl to the special value
"0
but
true"
. This special string is even exempt from the
-w
flag's pesky non-numeric warnings, so feel free to use it in your functions when you want to return a value that's numerically zero yet still true. It probably should have been
"0
and
sneaky"
instead.
The
socket
,
bind
,
listen
,
accept
,
fcntl
,
setsockopt
, functions in
Chapter 3
of
Programming Perl
and in
perlfunc
(1); your system's
fcntl
(2),
socket
(2),
setsockopt
(2) manpages (if you have them); the documentation for the standard Socket, IO::Socket, and Net::hostent modules; the section on
"Internet TCP Clients and Servers"
in
Chapter 6
of
Programming Perl
and in
perlipc
(1);
Unix Network Programming
;
Beej's Guide to Network Programming
at
http://www.ecst.csuchico.edu/~guide/net
;
Recipe 7.13
;
Recipe 7.14
;
Recipe 17.1
;
Recipe 17.3
;
Recipe 17.7