« 積雪7.9cm也 | Home | 縁談襲来 »
February 17, 2008
Java読書会の予習: Javaネットワークプログラミングの神髄 (Part 1)
今月からJava読書会に参加する予定だ。課題図書はJavaネットワークプログラミングの神髄である。予習課題が出ているので早速やってみた。
RFCの参照方法
RFCはどこに行けば見る事ができるかという課題。やはり本家IETF RFC pageだろう。URLはhttp://www.ietf.org/rfc。日本語だとRFC日本語版リストがリンク集としてよくまとまっている。
IPv6アドレスの表記について
IPv6のテキストでの表記で推奨されているのは、x:x:x:x:x:x:x:xの形式。xはIPv6のアドレスを8つの16ビット部に分けて16進数で表した値。これがRFC2373のどこに書かれているかという課題。RFC2373のセクション2.2にこのような記述がある。
2.2 Text Representation of Addresses
There are three conventional forms for representing IPv6 addresses as
text strings:
1. The preferred form is x:x:x:x:x:x:x:x, where the 'x's are the
hexadecimal values of the eight 16-bit pieces of the address.
(以下略)
JavaのIPv6サポートについて
本書によると、JDK1.4からは、ホストがIPv6とIPv4をサポートしているプラットフォームなら、IPv4とIPv6の両方をサポートするという。そのことを確かめてみよという課題。本書にあるEchoServerを実装してnetstatで見てみた。サーバのListen Portは50000。Mac OS X (tiger)でテストした。もちろんIPv6をサポートしている。
netstat | grep 50000 tcp6 0 0 localhost.50000 localhost.58159 ESTABLISHED tcp6 0 0 localhost.58159 localhost.50000 ESTABLISHED
ポート番号の範囲について
本書では「ポート番号のサイズが16ビットなので1から65535までである」とある。
IANAのport numberのリストによると
ポート番号はReservedとShirt Pocket netTunes、launchTunesに割り当てられている。
さてどう解釈すれば良いのかという課題。IANA port numberリストのポート番号の列挙が始まる前に
A value of 0 in the port numbers registry below indicates that no port has been allocated.
とある。うーむポート0は割り当てられていないと読めるのだが。そもそも全然Reservedではないではないか。ちなみにShirt PocketのnetTunesやlaunchTunesというのはリモートでiTuneを操作するためのソフトウェアのようだ。
TCP低レベルの通信
TCPコネクションのハンドシェイクをパケットキャプチャで確かめてみよという課題。tcpdumpでパケットをモニタした。結果を以下に示す。一番左の番号は行番号である。クライアントからサーバにHelloという文字列を送信し、Helloという文字列を受信した。
1: IP client > server: S 958024621:958024621(0) 2: IP server > client: S 2776186418:2776186418(0) ack 958024622 3: IP client > server: . ack 1 4: IP client > server: P 1:8(7) ack 1 5: IP server > client: . ack 8 6: IP server > client: P 1:8(7) ack 8 7: IP client > server: . ack 8 8: IP client > server: F 8:8(0) ack 8 9: IP server > client: . ack 9 10: IP server > client: F 8:8(0) ack 9 11: IP client > server: . ack 9
1-3行目が接続、4-7行目がデータ転送、8-11行目が切断のためのパケットのやりとりである。1-3行目では、クライアントがサーバにSYNを送り、SYN/ACKをサーバが返し、その応答としてクライアントがサーバにACKを返している。また8-11行目の切断では、クライアントがFINを送りサーバがACKで応答、その後サーバもクライアントにFINを送りクライアントがACKで応答している。
また、サーバがストリームからを2byteづつデータを取得し、2byteづつEchoする場合のパケットキャプチャの結果を示す。
1: IP client > server: S 1949917932:1949917932(0) 2: IP server > client: S 3839154648:3839154648(0) ack 1949917933 3: IP client > server: . ack 1 4: IP client > server: P 1:8(7) ack 1 5: IP server > client: . ack 8 6: IP server > client: P 1:3(2) ack 8 8: IP server > client: P 3:5(2) ack 8 9: IP client > server: . ack 5 10: IP server > client: P 5:7(2) ack 8 11: IP client > server: . ack 7 12: IP server > client: P 7:8(1) ack 8 13: IP client > server: . ack 8 14: IP client > server: F 8:8(0) ack 8 15: IP server > client: . ack 9 16: IP server > client: F 8:8(0) ack 9 17: IP client > server: . ack 9
4-13行目がデータ送受信の記録である。5行目でサーバはきちんと8byteを受信しACKを返している。 サーバは受信バッファから2byteづつ読み、クライアントに読んだ文字を送信しているため、2byte毎の送信、ACK応答が見られる。
前半の30ページくらいをざっと読んだが、間違いを見つけた。13ページの表2.2で、IPv6の::0がすべてのローカルIPアドレスであると書いてあるが、RFC2373によると、::0はunspecified addressと呼ばれる、アドレスが割り当てられていないことを示すアドレスである。
2.5.2 The Unspecified Address The address 0:0:0:0:0:0:0:0 is called the unspecified address. It must never be assigned to any node. It indicates the absence of an address. One example of its use is in the Source Address field of any IPv6 packets sent by an initializing host before it has learned its own address. The unspecified address must not be used as the destination address of IPv6 packets or in IPv6 Routing Headers.
No TrackBacks
TrackBack URL: http://www.argv.org/~chome/blog/mt-tb.cgi/134

port0って、bindするときに指定すると勝手にport割り振られちゃうはずだけど、どうやってbindするんだろう?
KAME(BSD)だとin_pcbbind()の先のin_pcbbind_setup()のあたり。
手元のはもう古いけど、0を許すようなオプションはなさそうに見えるなぁ。
connect時はin_pcbconnect_setup()だと思うけど、特に0をチェックしたりはしてないっぽい(未確認)
だからBSDだと、自分は0をbindできないけどconnectはできるかも?
うーん、とりあえず使えりゃいいやって実装のソースみて済ませちゃいがちだけど、ちゃんとRFCも見なきゃダメだね。
って最近は仕事でやってないので勘弁w
JavaのSocketクラスのgetPort()でもSocketが接続されていないときに0を返すということになっているので、
SunもPort0は無いということを前提にしているみたい。debianの/etc/servicesも1から始まっているし。
>BSDだと、自分は0をbindできないけどconnectはできるかも?
そうか。connectできる可能性はあるのか。でもサーバはPort0にbindできないので、acceptできない。
よってクライアントが接続できても誰もレスポンスを返せないので意味はないかぁ。
どーなっとんじゃぁ! >IANA
ってか、実装から当たるってとこがさすがですねぇ >pirafu