ソケット
ソケット概要ソケット例文TCP-SRVTCP-MSRVTCP-RCV
UDP-SRVUDP-RCVacceptbindconnect
gethostbyaddrgethostbynamegetpeernamegetprotobynamegetservbyname
getsocknamegetsockoptinet_atoninet_ntoalisten
recvsendselectsetsockoptshutdown
sockaddr_insocket

元に戻る。

ソケット目次に戻る。
ソケットは外部コンピュータとの間でTCP/IPやUDP通信を行うための インターフェースである。 ソケット通信はファイルと同様にソケットをオープンし、 通信を行い、ソケットをクローズする。
名称番号目的
FTP21ファイル転送
Telnet23遠隔操作
SMTP25メール送信
HTTP80ホームページ
POP3110メール受信
TCPクライアント
1) socketでソケットをオープン
2) connectでリモートアドレスに接続
3) send, recvまたはprint,read,<>でデータの送受
4) closeでソケットをクローズ

TCPサーバ
1) socketでソケットをオープン
2) bindでソケットにローカルアドレスを割り当てる
3) listenでソケットが接続を受け付けることをシステムに知らせる
4) acceptでクライアントからの接続を受け付ける
5) connect要求があればソケットを自動的にオープンする
6) send, recvまたはprint,read,<>でデータの送受
7) closeでソケットをクローズ
8) 5)へ戻る

UDPクライアント
1) socketでソケットをオープン
2) bindでソケットにローカルアドレスを割り当てる
3) send(宛先を指定)、recvでデータの送受
4) closeでソケットをクローズ

UDPサーバ
1) socketでソケットをオープン
2) bindでソケットにローカルアドレスを割り当てる
3) recvでデータの受信
4) sendで返事をする
5) 3)へ戻る

ソケット例文目次に戻る。
以下のソケット例文は中島 靖著
Perl徹底活用インターネットダイレクトアクセス 
p.40 に掲載されているプログラムである。

ソケットTCPサーバプログラム目次に戻る。
#!/usr/bin/perl use Socket; # コマンドラインからポート番号を得る。 $port= shift || 9999; # プロトコル番号を得る。 $proto=getprotobyname('tcp'); # listenするソケットをオープンする。 socket(ListenSock,PF_INET,SOCK_STREAM,$proto) or die("ソケットがオープン出来ない:$!\n"); # bindする bind(ListenSock,sockaddr_in($port,INADDR_ANY)) or die("ソケットがbindできない:$!\n"); # listenする listen(ListenSock,SOMAXCON); # 待機し、接続要求があれば日時を返す print "ポート番号:$port で待機開始\n"; while($sockaddr=accept(ConnectSock,ListenSock)){ select(ConnectSock); $|=1; select(STDOUT); # クライアントからポート番号、IP、ホスト名を得る my($port,$ipaddr)=sockaddr_in($sockaddr); my $name = gethostbyaddr($ipaddr,AF_INET); $ipaddr=inet_ntoa($ipaddr); print "$name($ipaddr)のポート番号$portから接続\n"; # 日時を返す。 print ConnectSock "Hello $name, now ",scalar localtime, "\n"; close(ConnectSock); } # 終了 close(ListenSock); exit;
ソケットTCPマルチサーバプログラム目次に戻る。
fork()を利用して多重受け付けを行う。 #!/usr/bin/perl # ソケットTCPサーバプログラム(並行処理) use Socket; # コマンドラインからポート番号を得る。 $port= shift || 9999; # プロトコル番号を得る。 $proto=getprotobyname('tcp'); # listenするソケットをオープンする。 socket(ListenSock,PF_INET,SOCK_STREAM,$proto) or die("ソケットがオープン出来ない:$!\n"); # 複数接続設定 setsockopt(ListenSock,SOL_SOCKET,SO_REUSEADDR,1) or die("ソケットオプションが設定出来ない:$!\n"); # bindする bind(ListenSock,sockaddr_in($port,INADDR_ANY)) or die("ソケットがbindできない:$!\n"); # listenする listen(ListenSock,5); # 待機し、接続要求があれば日時を返す print "ポート番号:$port で待機開始\n"; while( $sockaddr = accept(ConnectSock,ListenSock) ) { my $pid; # クライアントからポート番号、IP、ホスト名を得る my($port,$ipaddr)=sockaddr_in($sockaddr); my $name = gethostbyaddr($ipaddr,AF_INET); $ipaddr=inet_ntoa($ipaddr); print "$name($ipaddr)のポート番号$portから接続\n"; # forkして並行処理 if( !defined($pid = fork) ) # fork できない { print "fork できない: $!\n"; } elsif( $pid ) # 親プロセス { print "子プロセス($pid)開始\n"; } else # 子プロセス { # 待機用プロセスは閉じる close(ListenSock); # 日時を返す print ConnectSock "Hello $name, now ",scalar localtime, "\n"; # 子プロセス終了 close(ConnectSock); exit; } # 親プロセスは接続を終了し、待機ループに戻る close(ConnectSock); } # 終了 close(ListenSock); exit;
ソケットTCPクライアントプログラム目次に戻る。
#!/usr/bin/perl use Socket; # コマンドラインからホスト名とサービス名を得る。 $host = shift || 'localhost'; $port= shift || 9999; # プロトコル番号を得る。 $port=getservebyname($port,'tcp') if($port =~ /\D/); die("指定されたポートがない\n") unless($port); # ホスト名->IPアドレス、IPアドレスとポート番号->ソケットアドレス $ipaddr=inet_aton($host) or die("$hostが見つからない\n"); $sockaddr=sockaddr_in($port,$ipaddr); # プロトコル番号を得る。 $proto=getprotobyname('tcp'); # ソケットをオープンし、接続する。 socket(SOCK,PF_INET,SOCK_STREAM,$proto) or die("ソケットがオープンできない:$!\n"); connect(SOCK,$sockaddr) or die("ソケットが接続できない:$!\n"); # サーバからのデータを全て表示する while(<SOCK>){ print; } # ソケットを閉じて終了する。 close(SOCK) or die("ソケットがクローズできない:$!\n"); exit;
ソケットUDPサーバプログラム目次に戻る。
#!/usr/bin/perl use Socket; # コマンドラインからポート番号を得る。 $port= shift || 9999; # プロトコル番号を得る。 $proto=getprotobyname('udp'); # listenするソケットをオープンする。 socket(SOCK,PF_INET,SOCK_DGRAM,$proto) or die("ソケットがオープン出来ない:$!\n"); # bindする bind(SOCK,sockaddr_in($port,INADDR_ANY)) or die("ソケットがbindできない:$!\n"); # 待機し、接続要求があれば日時を返す print "ポート番号:$port で待機開始\n"; while($sockaddr=recv(SOCK,$_,1000,0)){ # クライアントからポート番号、IP、ホスト名を得る my($port,$ipaddr)=sockaddr_in($sockaddr); my $name = gethostbyaddr($ipaddr,AF_INET); $ipaddr=inet_ntoa($ipaddr); print "$name($ipaddr)のポート番号$portから接続\n"; # 日時を返す。 send(SOCK,"Hello $name, now ".(scalar localtime)."\n",0,$sockaddr) } # 終了 close(SOCK); exit;
ソケットUDPクライアントプログラム目次に戻る。
#!/usr/bin/perl use Socket; use Sys::Hostname; # コマンドラインからホスト名とサービス名を得る。 $host = shift || 'localhost'; $port= shift || 9999; # プロトコル番号を得る。 $port=getservebyname($port,'udp') if($port =~ /\D/); die("指定されたポートがない\n") unless($port); # ホスト名->IPアドレス、IPアドレスとポート番号->ソケットアドレス $ipaddr=inet_aton($host) or die("$hostが見つからない\n"); $sockaddr=sockaddr_in($port,$ipaddr); # プロトコル番号を得る。 $proto=getprotobyname('udp'); # ソケットをオープンし、接続する。 socket(SOCK,PF_INET,SOCK_DGRAM,$proto) or die("ソケットがオープンできない:$!\n"); # ローカルアドレスをbindする bind(SOCK,sockaddr_in(0,scalar gethostbyname(hostname()))); # 空パケットを送る。 send(SOCK,0,0,$sockaddr); # サーバからのパケットを受信する。 recv(SOCK,$_,1000,0); print; # ソケットを閉じて終了する。 close(SOCK) or die("ソケットがクローズできない:$!\n"); exit;

accept目次に戻る。
accept(NEWSOCKET,GENERICSOCKET) クラインアントからの接続要求を待ち、NEWSOCKETをオープンする。 失敗すると偽を返す。 GENERICSOCKETはsocket()でオープンされ、bind()でサーバに アロケートされた受信ソケットアドレス。
bind目次に戻る。
bind(SOCKET,SOCKADDR) ソケットSOCKETにローカルアドレスSOCKADDRを割り当てる。 SOCKADDRはIP+ポート番号をパックした値で、sockaddr_in()で 作成する。失敗すると偽を返す。
connect目次に戻る。
connect(SOCKET,SOCKADDR) ソケットSOCKETにリモートアドレスSOCKADDRを接続する。 失敗すると偽を返す。
gethostbyaddr目次に戻る。
gethostbyaddr(IPADDR,ADDRTYPE) IPアドレスから情報を得る。
gethostbyname目次に戻る。
gethostbyname(NAME) ホスト名から情報を得る。
getpeername目次に戻る。
getpeername(SOCKET) ソケットSOCKETの接続リモートアドレスを返す。
getprotobyname目次に戻る。
プロトコル番号を得る。TCPまたはUDPである。 TCPなら、 $proto=getprotobyname('tcp'); UDPなら、 $proto=getprotobyname('udp');
getservbyname目次に戻る。
getservbyname Port, Proto getservbyname(3)と同等の作業をする。 Port番号ににプロトコールを指定する。 例: $port = shift || 2345; # 適当なポート番号 If ($port =~ /\D/) {$port = getservbyname($port, 'tcp')} die "No port" unless $port;
getsockname目次に戻る。
getsockname(SOCKET) ソケットSOCKETの接続ローカルアドレスを返す。
getsockopt目次に戻る。
getsockopt(SOCKET,LEVEL,OPTNAME) ソケットSOCKETのオプションの値を返す。
inet_aton目次に戻る。

inet_ntoa目次に戻る。

listen目次に戻る。
listen(SOCKET,QUESIZE) ソケットSOCKETがQUESIZE個受け付けるように設定する。 成功すれば1、失敗すれば0を返す。 QUESIZEを最大値に設定するにはSOMAXCONNを指定する。
recv目次に戻る。
recv(SOCKET,SCALAR,LENGTH,FLAGS) SOCKETからLENGTHバイトのメッセージを受信し、SCALARに記録する。 成功すると送信元のアドレスを、失敗すれば未定義を返す。
send目次に戻る。
send(SOCKET,MSG,FLAGS[,TO]) SOCKETへMSGを送信する。成功すると送信バイト数、 失敗すれば未定義を返す。 UDPでは送信先TOを指定する。
select目次に戻る。

setsockopt目次に戻る。
setsockopt(SOCKET,LEVEL,OPTNAME,OPTVAL) SOCKETにオプション名、値を設定する。
shutdown目次に戻る。
shutdown(SOCKET,HOW) HOW値に従ってSOCKETをクローズする。 HOW値は、0なら受信、1なら送信、2なら両方を指定する。
sockaddr_in目次に戻る。

socket目次に戻る。
socket(SOCKET,PROTOCOLFAMILY,TYPE,PROTOCOL) SOCKETをオープンする。 PROTOCOLFAMILYは、1でローカルドメイン、2でインターネットドメイン。 TYPEはTCPでは、SOCK_STREAM、UDPではSOCK_DGRAMを使用する。 TCP/SERVER側、ソケットオープン socket(ListenSock,PF_INET,SOCK_STREAM,$proto) or die("ソケットがオープン出来ない:$!\n"); TCP/CLIENT側、ソケットオープン socket(SOCK,PF_INET,SOCK_STREAM,$proto) or die("ソケットがオープンできない:$!\n"); UDP/SERVER側、ソケットオープン socket(SOCK,PF_INET,SOCK_DGRAM,$proto) or die("ソケットがオープン出来ない:$!\n"); UDP/CLIENT側、ソケットオープン socket(SOCK,PF_INET,SOCK_DGRAM,$proto) or die("ソケットがオープンできない:$!\n");
目次に戻る。

目次に戻る。

目次に戻る。