« 積雪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

2 Comments

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

About this Entry

This page contains a single entry by chomy published on February 17, 2008 6:31 AM.

積雪7.9cm也 was the previous entry in this blog.

縁談襲来 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.