On the networking side, the most basic is BSD socket programming, but often when Perl is getting started in this area, the biggest headache is undoubtedly how to start, how to step by step. The best remedy is example, a complete code that can be run (working), which is more deeply felt by practice than by the boring manual.
Here are a few paragraphs of server/client written using sockets and io::socket to achieve the simplest but most basic tasks, including a forking/accept model. You can copy the code directly, then add small modifications to develop some small tcp/udp applications.
TCP Client, Socket module
Introduction: Implementation reads a line of information from the server side and returns
Copy Code code as follows:
#!/usr/bin/perl-w
# tcp_socket_cli.pl
Use strict;
Use Socket;
My $addr = $ARGV [0] | | ' 127.0.0.1 ';
My $port = $ARGV [1] | | ' 3000 ';
My $dest = sockaddr_in ($port, Inet_aton ($ADDR));
my $buf = undef;
Socket (sock,pf_inet,sock_stream,6) or die "Can ' t create socket: $!";
Connect (sock, $dest) or die "Can ' t connect: $!";
My $bs = Sysread (sock, $buf, 2048); # try to read 2048
Print "Received $bs bytes, content $buf \ n"; # actually get $bs bytes
Close sock;
Execution results:
Perl tcp_socket_cli.pl localhost 25
Received bytes, content ESMTP Postfix-extmail 0.12-HZQBBC
TCP Server socket module, forking/accept model
Introduction: A multi-process TCP server, sample in the implementation of the daytime function
Copy Code code as follows:
#!/usr/bin/perl-w
# tcp_socket_dt_srv.pl
Use strict;
Use Socket;
Use Io::handle;
Use POSIX QW (Wnohang);
My $port = $ARGV [0] | | ' 3000 ';
My $proto = getprotobyname (' TCP ');
$SIG {' chld '} = sub {
while ((My $pid = Waitpid ( -1, Wnohang)) >0) {
Print "reaped child $pid \ n";
}
};
Sockets (sock, Af_inet, Sock_stream, Getprotobyname (' TCP '))
Or die "socket () failed: $!";
SetSockOpt (sock,sol_socket,so_reuseaddr,1)
Or die "Can ' t set so_reusaddr: $!";
My $my _addr = sockaddr_in ($port, Inaddr_any);
Bind (sock, $my _addr) or Die "bind () failed: $!";
Listen (Sock,somaxconn) or Die "Listen () failed: $!";
Warn "Starting server on port $port ... \ n";
while (1) {
Next unless my $remote _addr = accept (Session,sock);
Defined (my $pid =fork) or die "Can ' t fork: $!\n";
if ($pid ==0) {
My ($port, $hisaddr) = sockaddr_in ($remote _addr);
Warn "Connection from [", Inet_ntoa ($HISADDR), ", $port]\n";
Session->autoflush (1);
Print session (My $s = localtime);
Warn "Connection from [", Inet_ntoa ($HISADDR), ", $port] finished\n";
Close session;
Exit 0;
}else {
Print "Forking child $pid \ n";
}
}
Close sock;
Use the above tcp_socket_cli.pl to access the server's execution results:
[Hzqbbc@local misc]$ Perl tcp_socket_dt_srv.pl
Starting server on port 3000 ...
Connection from [127.0.0.1,32888]
Connection from [127.0.0.1,32888] finished
Reaped child 13927
Forking Child 13927
TCP Client, Io::sockiet module
Introduction: Also for the client, but using the Io::socket object-oriented module
Copy Code code as follows:
#!/usr/bin/perl-w
# tcp_iosocket_cli.pl
Use strict;
Use Io::socket;
My $addr = $ARGV [0] | | ' 127.0.0.1 ';
My $port = $ARGV [1] | | ' 3000 ';
my $buf = undef;
My $sock = Io::socket::inet->new (
Peeraddr => $addr,
Peerport => $port,
Proto => ' TCP ')
Or die "Can ' t connect: $!\n";
$buf = < $sock >;
My $bs = Length ($BUF);
Print "Received $bs bytes, content $buf \ n"; # actually get $bs bytes
Close $sock;
TCP server, Io::socket module, forking/accept model
Introduction: The same one daytime
Server, using Io::socket overrides.
Copy Code code as follows:
#!/usr/bin/perl
# tcp_iosocket_dt_srv.pl
Use strict;
Use Io::socket;
Use POSIX QW (Wnohang);
$SIG = SUB {
while ((My $pid = Waitpid ( -1, Wnohang)) >0) {
Print "reaped child $pid \ n";
}
};
My $port = $ARGV [0] | | ' 3000 ';
My $sock = io::socket::inet->new (Listen => 20,
LocalPort => $port,
Timeout => 60*1,
Reuse => 1)
Or die "Can ' t create listening socket: $!\n";
Warn "Starting server on port $port ... \ n";
while (1) {
Next unless my $session = $sock->accept;
Defined (my $pid = fork) or die "Can ' t fork: $!\n";
if ($pid = = 0) {
My $peer = gethostbyaddr ($session->peeraddr,af_inet) | | $session->peerhost;
My $port = $session->peerport;
Warn "Connection from [$peer, $port]\n";
$session->autoflush (1);
Print $session (My $s = localtime), "\ n";
Warn "Connection from [$peer, $port] finished\n";
Close $session;
Exit 0;
}else {
Print "Forking child $pid \ n";
}
}
Close $sock;
Now we introduce the use of socket and Io::socket module for UNIX domain socket Client/server development. UNIX Domain sockets (Unix sockets, for short) and TCP/UDP inet type sockets have several advantages:
1, high Security, UNIX socket only in a stand-alone environment to use, does not support communication between machines
2, high efficiency, the speed of execution is about twice times that of TCP, more for operating system internal communication (IPC)
3), support SOCK_DGRAM, but unlike UDP, before and after the message is strictly ordered
Therefore, using UNIX sockets to design a stand-alone IPC application is preferred. Very practical. A large number of UNIX applications use UNIX sockets for communication between programs.
Unix Domain socket client, Socket module
Introduction: Clients using UNIX domain sockets.
Copy Code code as follows:
#!/usr/bin/perl-w
Use strict;
Use Socket;
Use Io::handle;
My $path = $ARGV [0] | | '/tmp/daytime.sock ';
Socket (my $sock, Pf_unix, Sock_stream, 0);
My $sun = Sockaddr_un ($path);
Connect ($sock, $sun) or die "Connect: $!\n";
$sock->autoflush (1);
My $buf = < $sock >;
My $bs = Length ($BUF);
Print "Received $bs bytes, content $buf \ n";
Close $sock;
Unix Domain socket service side, Socket module
Introduction: A daytime server that is implemented using UNIX domain sockets.
Copy Code code as follows:
#!/usr/bin/perl-w
# tcp_socket_dt_srv.pl
Use strict;
Use Socket;
Use Io::handle;
Use POSIX QW (Wnohang);
My $path = $ARGV [0] | | '/tmp/daytime.sock ';
$SIG {' chld '} = sub {
while ((My $pid = Waitpid ( -1, Wnohang)) >0) {
Print "reaped child $pid \ n";
}
};
Sockets (sock, Pf_unix, Sock_stream, 0)
Or die "socket () failed: $!";
SetSockOpt (sock,sol_socket,so_reuseaddr,1)
Or die "Can ' t set so_reusaddr: $!";
Unlink $path if-r $path;
Bind (Sock,sockaddr_un ($path)) or Die "bind () failed: $!";
Listen (Sock,somaxconn) or Die "Listen () failed: $!";
Warn "Starting server on path $path ... \ n";
while (1) {
Next unless my $sockname = accept (Session,sock);
Defined (my $pid =fork) or die "Can ' t fork: $!\n";
if ($pid ==0) {
Session->autoflush (1);
Print session (My $s = localtime);
Close session;
Exit 0;
}else {
Print "Forking child $pid \ n";
}
}
Close sock;