In networking, BSD socket programming is the most basic. But when perl is getting started, the biggest headache is how to start and how to Step by step. The best prescription is Example. A complete piece of code that can run (working) is far more profound than the boring manual.
The following sections describe Socket and IO: Server/client written by Socket, which can implement the simplest but most basic tasks, including a forking/accept model. You can directly copy the code and then modify it to develop some small tcp/udp applications.
TCP client, Socket module
Introduction: Read a row of information from the server and then return
Copy codeThe Code is as follows :#! /Usr/bin/perl-w
# Tcp_socket_cli.pl
Use strict;
Use Socket;
My $ addr = $ ARGV [0] | '2017. 0.0.1 ';
My $ port = $ ARGV [1] | '123 ';
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 result:
Perl tcp_socket_cli.pl localhost 25
Received 41 bytes, content 220 ESMTP Postfix-ExtMail 0.12-hzqbbc
TCP server Socket module, forking/accept Model
Introduction: a multi-process TCP server implements the daytime function in the sample.
Copy codeThe Code is 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] | '123 ';
My $ proto = getprotobyname ('tcp ');
$ SIG {'chld '} = sub {
While (my $ pid = waitpid (-1, WNOHANG)> 0 ){
Print "Reaped child $ pid \ n ";
}
};
Socket (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 result:
[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: it is also a client, but I/O: Socket object-oriented module is used.
Copy codeThe Code is as follows :#! /Usr/bin/perl-w
# Tcp_iosocket_cli.pl
Use strict;
Use IO: Socket;
My $ addr = $ ARGV [0] | '2017. 0.0.1 ';
My $ port = $ ARGV [1] | '123 ';
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 daytime
Server, rewrite with IO: Socket.
Copy codeThe Code is 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] | '123 ';
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 will introduce the use of Socket and IO: Socket module for client/server development of Unix domain Socket. Unix Domain Socket (unix socket) has several advantages over INET socket types such as TCP and UDP:
1) high security. unix socket is only used in a single-host environment and does not support inter-machine communication.
2) High Efficiency: the execution speed is about twice the speed of TCP. It is mostly used for internal communication (IPC) of the operating system)
3) supports SOCK_DGRAM, but unlike UDP, messages are strictly ordered before and after
Therefore, it is the first choice to use Unix socket to design single-host IPC applications. Very practical. A large number of Unix applications use unix socket for inter-program communication.
Unix Domain Socket Client, Socket module
Introduction: a client that uses Unix domain socket.
Copy codeThe Code is 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 server, Socket module
Introduction: daytime server implemented using Unix domain socket.Copy codeThe Code is 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 ";
}
};
Socket (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;