計算数学Ⅰ実習のためにUnix/Linuxでのネットワークプログラムの例として作成した簡単なメッセージボードのサーバとクライアントのプログラムについて説明する。
2016年6月現在、
- MaxOS X 10.11.5
- Ubuntu 16.04 LTS
- FreeBSD 10.3-RELEASE-p5
- NetBSD 7.0.1
- cygwin 2.5.2
で動作確認している。 IPv4/IPv6 いずれでも動作する。 cygwin でサーバを動作させるにはWindowsのファイアウォール設定を変更する必要がある。
以下の動作例はUbuntu 16.04 LTS上のものである。
もしmakeやgccというコマンドがないと言われたら
$ sudo apt-get install make gcc
で導入しておいてください。 ファイルをダウンロードして展開したら
$ cd message
$ make
でできるはず。
$ ./msgbd-server ポート番号
「ポート番号」は 49152 ~ 65535 の適当なポート番号。たとえば 55555 など。
$ ./msgbd-client サーバのホスト名又はIPアドレス ポート番号
「ポート番号」はサーバ側で与えたのと同じ番号。
コマンドはアルファベット(ASCII)大文字1文字からなる。オプションがある場合もある。
P name
message
"name"はPのあとに半角スペース(ASCII 0x20)をはさんで最大1020バイトの文字列(改行で終端)。 "message"は最大1022バイトの1行(改行で終端)。
R
サーバに蓄積されているメッセージ(最大1000メッセージ)が全て表示される。
Q
接続を切り、クライアントプログラムを終了する。
H
コマンドの簡単な一覧を表示する。
なお、"name" および "message" にはUTF-8の日本語なども入れられるかもしれないが、プログラム上は何も考えていないので文字化けする場合がある。
クライアント側が送出するコマンド及びそれに対するサーバ側からのレスポンスはいずれも TCP 上のテキスト(ASCII)ベース、行単位(CRLF = '¥r' + '¥n' 終端)。
R コマンドに対するサーバ側からクライアント側へのメッセージ本体送信を除き、各コマンド、レスポンスは最大1024バイト(CRLF含む)。
コマンドは以下のいずれか。
"P" + SPC + name + CRLF + message + CRLF
- SPC : ASCII 0x20(スペース)
- name: 最大1020 (= 1024 - 2 - 2) バイト
- message: 最大 1022 (= 1024 - 2) バイト
"R" + CRLF
"Q" + CRLF
レスポンスは
[0-9][0-9][0-9] + SPC + desciption + CRLF
[0-9] は 0 から 9 の数字(ASCII 0x31 ~ 0x39)で、3桁でメッセージの種類を表す。
定義されているレスポンスは
RESPONSE_HELLO "201 HELLO\r\n"
RESPONSE_POST_OK "202 POST OK\r\n"
RESPONSE_MESSAGE_ENDS "203 MESSAGE ENDS\r\n"
RESPONSE_BYE "209 BYE\r\n"
RESPONSE_POST_GOAHEAD "301 POST GO AHEAD\r\n"
RESPONSE_MESSAGE_FOLLOWS "302 MESSAGE FOLLOWS\r\n"
で、シーケンスは以下の通り。P と R は任意の順序で任意の回数行ってよい。
クライアント | サーバ | |
---|---|---|
起動 | → TCP 接続 | |
← 201 | 受付 | |
送信開始 | → P | |
← 301 | 送信受付 | |
メッセージ送信 | → message | |
← 202 | メッセージ受付 | |
受信 | → R | |
← 302 | 受信受付 | |
← messages | メッセージ送信 | |
← 203 | メッセージ送信完了 | |
終了 | → Q | |
← 209 | 終了受付 |
なお、クライアント側が Q コマンドを発行せず TCP connection を切断した場合(クライアント側プログラムが突然終了した場合を含む)もサーバ側は終了処理を行う。
- プロトコルもプログラムも短時間ででっち上げたものなので、バグがないことはもとより、コーディング例として適切であることも、全く保証しない。
- エラー処理は最低限しかしていないので、突然落ちたり、不思議な動きをすることがあっても驚いてはいけない。
- このプログラムでは、ユーザ入力やネットワークで送信されてきたものをそのまま扱っているが、インターネットで使うようなプログラムでそのようなことをしてはいけない。不正な入力とならないよう念には念を入れて確かめ、必要なら修正する必要がある(「サニタイズする」という)。このプログラムの場合、例えば誰かが文字の色を変えるエスケープシーケンスを入力すると、サーバも他のクライアントも影響を受けてしまう。適切にサニタイズするようプログラムを改良してみよ。
- サーバは一旦落ちるとそれまで蓄積したメッセージを全て失ってしまう(ディスクに書いてない)。
- 名前やメッセージにUTF-8コード(MacOS X, Linux, Windowsいずれも)で日本語(や中国語や韓国語や…)を入れることは可能だが、プログラム上は何の考慮もしていない(バッファなどは全て char)。クライアント側プログラムのライン入力環境で削除キーを押したときなど、プラットフォームによって動作が異なるようなので注意。
ネットワーク関係のコーディングは
萩野純一郎『IPv6ネットワークプログラミング』(アスキー、2003)
Jun-ichiro itojun Hagino, "IPv6 Network Programming" (Elsevier, 2005)
所収のサンプルをそっくりまねている。この本は IPv6 の存在を前提とし、v4/v6 デュアルスタック環境で自然に動作するプログラミングを解説した今も少ないテキストとして貴重。著者は Kame プロジェクトなどでIPv6 開発をリードし、itojun として世界的に知られた優れたプログラマ、研究者だったが、惜しくも 2007 年に亡くなった。その功績を記念するため、IPv6の発展に寄与した人物を表彰するItojun Service Award http://www.internetsociety.org/what-we-do/grants-and-awards/awards/itojun-service-award が設けられている。
同梱のmsgbot.py
はmsgbd-server
に接続するbot。