TCP/IP Socket in cをPerlで振り返るシリーズの第2弾です。
うまく説明はできないですが、EchoClientよりもEchoServerの方の方が試行錯誤が多かったなぁ。
・・・感想終わり・・・
って、それだとわざわざ外に出している日記の意味ような気もするけど、プログラムの中でコメントを多く書いているので、それでよしとしようではないか。
最近気になる事もあって、主にサーバーについての検証を書いていた時は、こーでもないあーでもないって風に失敗例も載せていたのだけど、プログラムの場合はコンパイルエラーが出たり、実行時にエラーが出たときにも、すぐに治して次に進んでしまうので、なかなか以前の日記のように、こーでもないあーでもないという部分がアウトプットできていないのな。
自分の頭には残されているのでそれほど気にしなくてもいいんだけどな、HowToサイトでもないしなぁ。
ちょっと話が逸れてしまいましたが、そんな悩みもある訳です。
そーす TCPEchoServer.pl
#TCPEchoサーバープログラム
#!/usr/bin/perl
use strict;
use warnings;
use Socket;
use IO::Handle;
#キューの最大数
my $MAXPENDING = 4;
#引数の数をチェック
if($#ARGV != 0)
{
print "Usage : Program <Server Port>\n";
exit(1);
}
#ポート番号を指定
my $port = $ARGV[0];
#TCPソケット生成
socket(SOCKET, PF_INET, SOCK_STREAM, 0) or die "Socket failed $!\n";
#アドレス構造体を作成
#ポートとアドレスをパック
my $sock_addr = pack_sockaddr_in($port, INADDR_ANY);
#バインド
bind(SOCKET, $sock_addr) or die "bind failed $!\n";
#りっすん
listen(SOCKET, $MAXPENDING) or die "listen failed $!\n";
while(1)
{
#接続要求待ち
my $cldata = accept(CLIENT, SOCKET) or die "accept failed $!\n";
#クライアントの情報を取得
my $client_addr = unpack_sockaddr_in($cldata);
#atonの逆すなわちバイナリから変換。
my $client_iaddr = inet_ntoa($client_addr);
print "Handling client $client_iaddr\n";
#while内で使う変数。
my $Buf;
my $messages;
#オートフラッシュは今回いらない。
#のちのちのために一応置いておこう。
#SOCKET->autoflush;
#CLIENT->autoflush;
#メッセージを受けとり出力する。
#forearchでもいい。ハッシュキーを使うときこの辺がめんどくさそ。
while($Buf=<CLIENT>)
{
my $messages = $Buf;
print CLIENT "$messages";
}
#読み込み終了を宣言=0
shutdown(CLIENT, 0);
#ソケットを閉じる。
close(CLIENT);
}
exit;実行結果 クライアント側
# perl TCPEchoClient.pl 192.168.24.61 おらおら 500 [/root/perl] RecvMessage:おらおら # perl TCPEchoClient.pl 192.168.24.61 むだむだ 500 [/root/perl] RecvMessage:むだむだ
実行結果 サーバー側
# perl TCPEchoServer.pl 500 [/root/perl] Handling client 192.168.24.63 Handling client 192.168.24.63
参考サイト
参考文献
TCP/IPソケットプログラミングC言語編
共著:Michael J.Donahoo/Kenneth L. calvert
訳:小高知宏