TCP/IP Socket in cをPerlで振り返るシリーズの第1弾として、最初のTCPEchoClientです。
今回はコピペじゃない事と、Perlのルールを調べる事と、Socket通信の復習という3本立てなので、わりと時間もかかったし、やりがいもありました。
完全なコピーにはできていないけど、Perlでの考え方を考えるという事はできたと思います。
プログラムももっと短くできたけど、見やすさを重視している部分は多々あって、個人的な裁量になるけれど、C言語に比べてPerlだとインデントがバチっと決まらないので、わざとC言語の時のように書いてみたりしました。
ソース TCPEchoClient.pl
TCPEchoClient.pl [/root/perl] #Echoクライアントプログラム #!/usr/local/bin/perl use strict; use warnings; use Socket; use IO::Handle; ##引数の数のチェック if( $#ARGV < 1 || $#ARGV > 2) { print "Usage: #program <Server IP> <Echo Word> [<Echo Port>]\n"; exit(1); } #コマンドラインからサーバ、メッセージを引っ張る。 my $ServerIP = $ARGV[0]; my $EchoWord = $ARGV[1]; #指定があればポート番号を代入。 my $port; if($#ARGV == 2) { $port = $ARGV[2]; } else { $port = getservbyname('echo', 'tcp'); } #TCPストリームソケットを作成 socket(SOCKET, PF_INET, SOCK_STREAM, 0) or die "Socket faild\n"; #アドレス構造体を作成 #ホスト名orIPアドレスをバイナリに変換 #ポートとIPアドレス(バイナリ)をパック my $addr = inet_aton($ServerIP) or die "pack error\n"; my $sock_addr = pack_sockaddr_in($port, $addr); #サーバへの接続を確立(CONNECT) connect(SOCKET, $sock_addr) or die "Connect failed\n"; #オートフラッシュ SOCKET->autoflush; #接続したサーバへメッセージ送信 print SOCKET "$EchoWord"; print SOCKET "\n"; #送信完了を送る(重要) shutdown(SOCKET, 1); #文字列をサーバから受信 print "RecvMessage:"; while(my $line = <SOCKET>) { print "$line"; } #ソケットを閉じる close(SOCKET); #正常に終了 exit;
実行結果
# perl TCPEchoClient.pl 192.168.24.61 Hello 5000 [/root/perl] RecvMessage:Hello
ソケットを作って、コネクトしてっていう流れはいつもと同じなので、ためしに80番にGETというメッセージを飛ばすとホストの設定によってはHTMLが返ってきます。
# perl TCPEchoClient.pl 192.168.24.61 "GET" 80 | head [/root/perl] RecvMessage:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <head> <title>Apache HTTP Server Test Page powered by CentOS</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style type="text/css"> body { background-color: #fff; color: #000; font-size: 0.9em; font-family: sans-serif,helvetica;
返ってこない場合もあります。理由は見たままです。
# perl TCPEchoClient.pl biglobe.ne.jp "GET" 80 | head [/root/perl] RecvMessage:<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>400 Bad Request</title> </head><body> <h1>Bad Request</h1> <p>Your browser sent a request that this server could not understand.<br /> </p> </body></html>
中の仕組みはTCPクライアントと同じですね。とくに気にしてなかったですが、これはなかなか奥が深いです。
ひとまずはこんな感じでしばらく進めていきたいと思います。
参考サイト
参考文献
TCP/IPソケットプログラミングC言語編
共著:Michael J.Donahoo/Kenneth L. calvert
訳:小高知宏