ルータ無しでのフラグメンテーション?

尾崎です。
いつもお世話になります。
ご回答ありがとうございました。今後調査させていただきます。

また、別の疑問が浮かんだのでお聞きしたいのですが、
IPは最大で65515バイトのデータを扱えるはずですが、
EthernetならばMTUが1500バイトということで
MTU以内にルータがIPパケットを分割(フラグメンテーション)化
しなければなりません。(完全理解TCP/IPネットワーク p.232参照)
いま、2台のPCをクロスEthernetケーブルで
直接接続して通信している場合も
フラグメンテーション化は行われているのと思うのですが、
ルータがないのでどれが処理を行っているのでしょうか?

お手数かけますがよろしくお願いします。

名前: 
尾崎敏之
日時: 
02/06/21 00:52

コメント

尾崎さん,こんばんわ。

>ご回答ありがとうございました。今後調査させていただきます。

いえいえ,あんまり役に立てずに,すみませんねぇ。
もし,何かわかったら,教えてもらえますか。私も知りたいので。

>フラグメンテーション化は行われているのと思うのですが、
>ルータがないのでどれが処理を行っているのでしょうか?

最初に,UDPメッセージを送信するときに,
コンピュータのTCP/IPプロトコル処理ソフトっていうんですか,
OSのプロトコル処理モジュールがフラグメントに分割してから,
パケットを送信します。
そうしないと,送信動作がうまくいきません。
要するに,ルータもコンピュータのIPも基本原理は同じなんです。

このメッセージは削除されました

おはようございます。

>ということは、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()によってポート番号を指定することによって
>何かメリットはあるのでしょうか?

あなた任せじゃなくて,自分でポート番号を決めることができます!
それで,どんなメリットがあるかって,聞かれると困ります。(笑)
それはアプリケーションによっていろいろと事情があるかもしれませんし,
ファイアウォールとかが影響する場合もあります。

ちょっと,長くなっちゃいました。

たいへん詳細なご回答ありがとうございました。
確かにおっしゃる通りです。
一般的な専門書のOSIの階層構造の説明で誤解を招いてしました。

MSSとは初めて耳にしたのですが・・。
ということは、
TCPのフラグメントの分割によって、Ethernetでは、
1つのセグメントは1500バイトより大きくならないということでしょうか?
すると次のIPでは、フラグメントの分割をする必要がなくなってしまった
ように思えます。
すなわち、TCPの場合、1つのIPパケット(1500バイト以下)には
必ずIPヘッダとTCPヘッダが付加されているとうことですか?
このことはUDPでも同じですか?

多々迷惑をおかけいたしますがよろしくお願いします。

こんにちわ。

>MSSとは初めて耳にしたのですが・・。

TCPはデータ長に制限がないので,データの分割は必須です。
ただ,IPのフラグメンテーションとは考え方が違ってまして,
フラグメンテーションの方は,一つのIPメッセージを分割するのに対して,
TCPの方は,ユーザデータを多数のIPメッセージに分割することになります。
つまり,TCPで分割された断片が,一つ一つのIPメッセージなる,ということで,
そのIPメッセージは分割されたものではありません。
ただ,TCPで分割して作った一つのIPメッセージをルータで運ぶ途中に,
MTUの小さな箇所があると,そこで,フラグメンテーションで分割されることはあります。
ちょっと,ややこしいですね。
で,このTCPの分割で登場するのがMSSで,
TCPはMTUからヘッダを差し引いてMSSを計算し,
それを超えないようにして,データを分割するわけです。
『完全理解TCP/IPネットワーク』(戸根勤著,日経BP社)の第1章52ページ辺りに,
その辺の,MSSを元にデータを分割するところの説明やパケットの例があります。
送信バッファの容量や,送信タイミングとの兼ね合いなどもあり,
ここは,結構面白いところです。
面白いと思うのは一部の人だけかもしれませんけど...

一方,UDPの方は,TCPのようなデータ分割の機能はなくて,
単純に,データを一つのIPメッセージに格納して送るだけです。
それが,MTUを超えると,そのままでは送れないので,
この場合は,IPが分割するわけです。
IPの分割は,フラグメンテーションという機能しかありませんから,
それを使って分割するっていうことですね。

>すなわち、TCPの場合、1つのIPパケット(1500バイト以下)には
>必ずIPヘッダとTCPヘッダが付加されているとうことですか?
>このことはUDPでも同じですか?

ビンゴ!
UDPの場合は,IPとUDPのヘッダが付くことになりますね。

>多々迷惑をおかけいたしますがよろしくお願いします。

迷惑なんてことはありません。
この掲示板も戸根勤の重要な活動の一つですから。

尾崎です。いつもお世話になります。

ありがとうございました。
「完全理解TCP/IPネットワーク」をもう一度読み直してみます。

ここで一つお聞きしたいのですが、
「完全理解TCP/IPネットワーク」のP.52下半分のところで
”1448バイト分のデータ”とありますが、
これはどこから計算されたのでしょうか?
Ethernet&IPパケットにおいては、MTU1500-TCPヘッダ20-IPヘッダ20=1460ではないのでしょうか?

こんばんわ。

>Ethernet&IPパケットにおいては、MTU1500-TCPヘッダ20-IPヘッダ20=1460ではないのでしょうか?

そうですね。普通,イーサネットだとMSSは1460バイトになります。
でも,図1-23に載せてあるパケットは,TCPのセグメントが1448バイトになってますね。
おやおや,困りました。(笑)

この例をよく調べてみると,TCPにオプションフィールドが付いており,
その分MSSが小さくなって1448バイトになってしまった,ということです。
でも,これは,例として相応しくないですね。
オプションフィールドが付かないようにして実験し,
その結果を載せるべきでした。
オプションフィールドを見落としてしまったのが失敗です。

>これはどこから計算されたのでしょうか?

計算したわけじゃなくて,
実験結果を吟味せずに,その結果を元にそのまま説明しただけ,
ということで,これは軽率でした。本当。
反省します。

ご指摘ありがとうございました。