おはようございます。
>ということは、PC内のIPモジュールが下位層のMTUの情報を >知っているということになりますが、なんだか不思議な感じがします。
現実の世界をよーく考えてみてください。 たとえば,TCPでデータをパケットに分割するところなどです。 TCPはMSS(Maxセグメントサイズ)を知らなければ, パケットの分割はできないはずです。 で,このMSSはMTUとヘッダサイズによって決まりますから, どこかで,MTUの情報を持っていることになるんですね。 TCPですらそういう状況ですから,IPがMTUを知らないはずはありません。 話は横道にそれますが,OSの構造に関する議論で, モノリシックな大きなカーネルとマイクロカーネル的な小さなカーネルの どちらが優れているかといった話,ご存知でしょうか? プログラムを分ければ,それだけ,相互のやり取りが増え,効率は低下していきます。 だから,下手に分割すると良くない,というところに今のところ落ち着いています。 そして,Windowsも,Linuxも,大半のUnix系OSも, 皆,比較的大きなカーネルになっています。 それと同じことで,IPとかTCPとか,役割が違いますから階層構造で考えますが, 実際のプログラムは両者を分けるとは限らないわけです。 全部分けちゃうと,IPはLANドライバと, いろいろな情報をやり取りなければ動かなくなってしまいますし, TCPもIPと緊密に連絡しないと動かなくなります。 その結果,それぞれのインタフェースは複雑化しますし, 相互に依存する部分も出てきます。 これでは,現実的なメリットは何もなく,デメリットだけになります。 要するに,OSI的な階層構造では現実は成り立たないんです。 OSIの階層構造は,『基本的な考え方』を整理するには有効ですが, それ以上のものではないんです。 さらに,考え方を整理するという面も, いわゆるトランスポート層以下しか通用しません。 セッション層以上の上位層は,現実のネットワークと発想が違いますから, 役に立たないと思った方がよいです。その点も,注意してください。 正直なところ,そういった事情を何も考えずに, OSIを解説している教科書をみると,残念な気持ちになるんです。
>Winsock環境です。
Winsockって,やったことないので...
>[1]ソケットとはIPアドレスとポート番号で一意に決められている
ソケットを考える前に,一つのコネクションをどうやって識別するか, という点をはっきりさせておきましょう。 コネクションは,送信元のアドレスとポート,宛先のアドレスとポート, この四つの組み合わせで識別します。 で,ソケットというのは,そうしたコネクションの情報を格納する 変数領域のようなものなわけですね。 それから,コネクションを確立する前にソケットを作りますから, ソケットには,まだ,コネクションの情報が確定していない, という状態があるわけです。 ここからが本題ですが, ソケットディスクリプタというのは, コネクションそのものを識別するものではなくて, その情報の入れ物であるソケットを識別するものです。 わかりやすく言えば,ソケットという一種の変数を示す, 間接的なポインタだと思えばいいわけです。 だから,コネクション確立前のソケットを考えると, ソケットのディスクリプタは確定しているけれど, コネクションは確立していない,っていう状態になります。 また,bindっていうのは, ソケットの中に自分側のアドレスやポート番号を書き込むことだ, と考えてもいいかもしれません。 それで,ソケットの中身が変わり,通信の状態は変わりますが, ソケットという入れ物自身は変わりませんから, ソケットディスクリプタそのものは,それ以前と同じです。 この説明でわかります?
>[2]クライアントでもbind()できるそうなのですが、 >これはbind()しなかった場合OSが自動的にポート番号を >割り当てると理解しているのですが、
そうです。 OSから見れば,『アプリケーションさん,あなたが指定しないんだったら, 私が適当な値を使っときますよ。それでいいですね。』ってな感じでしょうか。
>クライアントがbind()によってポート番号を指定することによって >何かメリットはあるのでしょうか?
あなた任せじゃなくて,自分でポート番号を決めることができます! それで,どんなメリットがあるかって,聞かれると困ります。(笑) それはアプリケーションによっていろいろと事情があるかもしれませんし, ファイアウォールとかが影響する場合もあります。
ちょっと,長くなっちゃいました。
More information about text formats
ソケットは一種の変数領域
おはようございます。
>ということは、PC内のIPモジュールが下位層のMTUの情報を
>知っているということになりますが、なんだか不思議な感じがします。
現実の世界をよーく考えてみてください。
たとえば,TCPでデータをパケットに分割するところなどです。
TCPはMSS(Maxセグメントサイズ)を知らなければ,
パケットの分割はできないはずです。
で,このMSSはMTUとヘッダサイズによって決まりますから,
どこかで,MTUの情報を持っていることになるんですね。
TCPですらそういう状況ですから,IPがMTUを知らないはずはありません。
話は横道にそれますが,OSの構造に関する議論で,
モノリシックな大きなカーネルとマイクロカーネル的な小さなカーネルの
どちらが優れているかといった話,ご存知でしょうか?
プログラムを分ければ,それだけ,相互のやり取りが増え,効率は低下していきます。
だから,下手に分割すると良くない,というところに今のところ落ち着いています。
そして,Windowsも,Linuxも,大半のUnix系OSも,
皆,比較的大きなカーネルになっています。
それと同じことで,IPとかTCPとか,役割が違いますから階層構造で考えますが,
実際のプログラムは両者を分けるとは限らないわけです。
全部分けちゃうと,IPはLANドライバと,
いろいろな情報をやり取りなければ動かなくなってしまいますし,
TCPもIPと緊密に連絡しないと動かなくなります。
その結果,それぞれのインタフェースは複雑化しますし,
相互に依存する部分も出てきます。
これでは,現実的なメリットは何もなく,デメリットだけになります。
要するに,OSI的な階層構造では現実は成り立たないんです。
OSIの階層構造は,『基本的な考え方』を整理するには有効ですが,
それ以上のものではないんです。
さらに,考え方を整理するという面も,
いわゆるトランスポート層以下しか通用しません。
セッション層以上の上位層は,現実のネットワークと発想が違いますから,
役に立たないと思った方がよいです。その点も,注意してください。
正直なところ,そういった事情を何も考えずに,
OSIを解説している教科書をみると,残念な気持ちになるんです。
>Winsock環境です。
Winsockって,やったことないので...
>[1]ソケットとはIPアドレスとポート番号で一意に決められている
ソケットを考える前に,一つのコネクションをどうやって識別するか,
という点をはっきりさせておきましょう。
コネクションは,送信元のアドレスとポート,宛先のアドレスとポート,
この四つの組み合わせで識別します。
で,ソケットというのは,そうしたコネクションの情報を格納する
変数領域のようなものなわけですね。
それから,コネクションを確立する前にソケットを作りますから,
ソケットには,まだ,コネクションの情報が確定していない,
という状態があるわけです。
ここからが本題ですが,
ソケットディスクリプタというのは,
コネクションそのものを識別するものではなくて,
その情報の入れ物であるソケットを識別するものです。
わかりやすく言えば,ソケットという一種の変数を示す,
間接的なポインタだと思えばいいわけです。
だから,コネクション確立前のソケットを考えると,
ソケットのディスクリプタは確定しているけれど,
コネクションは確立していない,っていう状態になります。
また,bindっていうのは,
ソケットの中に自分側のアドレスやポート番号を書き込むことだ,
と考えてもいいかもしれません。
それで,ソケットの中身が変わり,通信の状態は変わりますが,
ソケットという入れ物自身は変わりませんから,
ソケットディスクリプタそのものは,それ以前と同じです。
この説明でわかります?
>[2]クライアントでもbind()できるそうなのですが、
>これはbind()しなかった場合OSが自動的にポート番号を
>割り当てると理解しているのですが、
そうです。
OSから見れば,『アプリケーションさん,あなたが指定しないんだったら,
私が適当な値を使っときますよ。それでいいですね。』ってな感じでしょうか。
>クライアントがbind()によってポート番号を指定することによって
>何かメリットはあるのでしょうか?
あなた任せじゃなくて,自分でポート番号を決めることができます!
それで,どんなメリットがあるかって,聞かれると困ります。(笑)
それはアプリケーションによっていろいろと事情があるかもしれませんし,
ファイアウォールとかが影響する場合もあります。
ちょっと,長くなっちゃいました。