Perlソケットプログラミング
ソケットは「ソケット」とも呼ばれます。アプリケーションは通常、「ソケット」を通じてネットワークにリクエストを送信したり、ネットワークリクエストに応答したりして、コンピューター上のホストまたはプロセスが通信できるようにします。
この章では、Perl 言語でソケット サービスを使用する方法を学びます。
サーバーを作成する
socket関数を使用してソケットサービスを作成します。
bind関数を使用してポートをバインドします。
ポートでリッスンするには、listen関数を使用します。
クライアントリクエストを受信するには、accept関数を使用します。
クライアントの作成
socket関数を使用してソケットサービスを作成します。
connect関数を使用してソケットサーバーに接続します。
次の図は、クライアントとサーバー間の通信プロセスを示しています:
サーバーソケット関数
ソケット関数
Perlでは、socket()関数を使用してソケットを作成します。形式は次のとおりです:
socket( SOCKET, DOMAIN, TYPE, PROTOCOL );
パラメータ分析:
DOMAIN 作成されたソケットはプロトコルセットを指定します。 例:
AF_INET
は IPv4 ネットワーク プロトコルを意味しますAF_INET
表示IPv4网络协议AF_INET6
表示IPv6AF_UNIX
AF_UNIX
は意味しますローカルソケット (ファイルを使用)TYPE ソケットタイプは、接続指向か非接続かに応じて SOCK_STREAM または SOCK_DGRAM に分類できます
AF_INET6
は IPv6 を意味します PROTOCOL
(getprotobyname) である必要があります('tcp' ))[2]
。使用される実際のトランスポート プロトコルを指定します。 したがって、ソケット関数呼び出しは次のようになります:use Socket # 定义了 PF_INET 和 SOCK_STREAM socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2]);
bind( SOCKET, ADDRESS );
ネットワーク アドレス (10.12.12.168 など)
socket() を使用してソケットを作成した後は、使用されるプロトコルのみがソケットに与えられ、アドレスは割り当てられません。他のホストからの接続を受け入れる前に、bind() を呼び出してソケットにアドレスを割り当てる必要があります。 簡単な例は次のとおりです:
use Socket # 定义了 PF_INET 和 SOCK_STREAM $port = 12345; # 监听的端口 $server_ip_address = "10.12.12.168"; bind( SOCKET, pack_sockaddr_in($port, inet_aton($server_ip_address))) or die "无法绑定端口! \n";or die アドレスのバインドに失敗した後に実行されます。 setsockopt() オプション SO_REUSEADDR を設定して、ポートを即時再利用できるように設定します。 🎜pack_sockaddr_in()🎜関数はアドレスをバイナリ形式に変換します。 🎜🎜listen() 関数🎜🎜 ソケットがアドレスにバインドされると、listen() 関数は可能な接続リクエストのリッスンを開始します。ただし、これは信頼性の高いデータ フローが保証されている場合にのみ使用できます: 🎜
listen( SOCKET, QUEUESIZE );
SOCKET: ソケット記述子。
QUEUESIZE: 接続リクエストが到着すると、リスニング キューに入ります。接続リクエストが accept() によって受け入れられると、リスニング キューから削除されます。キューがいっぱいになると、新しい接続リクエストはエラーを返します。
接続が受け入れられると、成功の場合は 0 を返し、エラーの場合は -1 を返します。
accept() 関数
accept() 関数は、要求されたソケット接続を受け入れます。成功した場合はネットワーク アドレスの圧縮形式を返し、それ以外の場合は FALSE を返します:
accept( NEW_SOCKET, SOCKET );
SOCKET: ソケット記述子。
ADDRESS: ADDRESS はソケット アドレス (TCP/IP) であり、次の 3 つの要素が含まれます:
アドレス クラスター (TCP/IP、AF_INET、システムでは 2 である可能性があります)
ポート番号 (例: 21 )
ネットワーク アドレス (10.12.12.168 など)
accept() は通常、無限ループで使用されます:
while(1) { accept( NEW_SOCKET, SOCKT ); ....... }
上記の例では、クライアントのリクエストをリアルタイムで監視できます。
クライアント関数
connect() 関数
connect() システムコールは、ソケットの接続を設定します。パラメータはファイル記述子とホストアドレスです。
connect( SOCKET, ADDRESS );
以下は、サーバーソケットに接続されたインスタンスを作成します:
$port = 21; # ftp 端口 $server_ip_address = "10.12.12.168"; connect( SOCKET, pack_sockaddr_in($port, inet_aton($server_ip_address))) or die "无法绑定端口! \n";
完全な例
次に、すべてのソケット関数のアプリケーションを理解するために完全な例を使用します:
サーバーserver.plコード:
#!/usr/bin/perl -w # Filename : server.pl use strict; use Socket; # 使用端口 7890 作为默认值 my $port = shift || 7890; my $proto = getprotobyname('tcp'); my $server = "localhost"; # 设置本地地址 # 创建 socket, 端口可重复使用,创建多个连接 socket(SOCKET, PF_INET, SOCK_STREAM, $proto) or die "无法打开 socket $!\n"; setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, 1) or die "无法设置 SO_REUSEADDR $!\n"; # 绑定端口并监听 bind( SOCKET, pack_sockaddr_in($port, inet_aton($server))) or die "无法绑定端口 $port! \n"; listen(SOCKET, 5) or die "listen: $!"; print "访问启动:$port\n"; # 接收请求 my $client_addr; while ($client_addr = accept(NEW_SOCKET, SOCKET)) { # send them a message, close connection my $name = gethostbyaddr($client_addr, AF_INET ); print NEW_SOCKET "我是来自服务端的信息"; print "Connection recieved from $name\n"; close NEW_SOCKET; }
ターミナルを開いて次のコードを実行します:
$ perl sever.pl 访问启动:7890
client.pl コード:
#!/usr/bin/perl -w # Filename : client.pl use strict; use Socket; # 初始化地址与端口 my $host = shift || 'localhost'; my $port = shift || 7890; my $server = "localhost"; # 主机地址 # 创建 socket 并连接 socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2]) or die "无法创建 socket $!\n"; connect( SOCKET, pack_sockaddr_in($port, inet_aton($server))) or die "无法连接:port $port! \n"; my $line; while ($line = <SOCKET>) { print "$line\n"; } close SOCKET or die "close: $!";
別のターミナルを開いて次のコードを実行します:
$ perl client.pl 我是来自服务端的信息