5

TCP を使用して、固定の非標準 MTU (たとえば、1560) でサブネット経由でデータを送信する必要があります。フレームの長さが MTU 未満の場合、このサブネットを介して転送されるすべてのイーサネット フレームは、手動で 0 でパディングする必要があります。

したがって、データ サイズは (1560 - sizeof(IP ヘッダー) - sizeof(TCP ヘッダー)) である必要があります。

これは私がやろうとしている方法です:

  1. TCP_CORK オプションを設定して、データの断片化を減らしました。200 ミリ秒の上限があるため、信頼性は高くありませんが、機能します。

  2. IP ヘッダーのサイズ (20 バイト) はわかっているので、データ長は (1540 - sizeof( TCP ヘッダー )) に等しくなるはずです。

  3. それが問題です。TCP ヘッダーのサイズがわかりません。「オプション」フィールドのサイズは変動します。

問題は、TCP ヘッダーのサイズを取得する方法です。それとも、固定長のヘッダーを持つ TCP フレームを送信する方法があるのでしょうか?

4

4 に答える 4

10

ユーザー アプリケーションから TCP を使用するときにフレームのサイズを制御しようとするのは誤りです。間違った抽象化レベルで作業しています。それも無理です。

あなたがすべきことは、TCP を別のもの (UDP?) に置き換えることを検討するか、可能性は低いですが、イーサネット ドライバーを書き直して非標準の MTU を設定し、必要なパディングを行うことです。

于 2011-05-31T14:43:44.993 に答える
6

ホストの TCP スタックを使用してこれを行うことはできません。単純に、RFC 793 に準拠する TCP スタックは、この種のアプリケーションへのアクセスを提供することが想定されていないためです。

つまり、下位層がデータをどう処理するかに影響を与える方法はありません (また、あるべきではありません)。もちろん、何に影響を与えるかTCP(Nagle など) に影響を与える方法はありますが、それはプロトコルの精神に反します。TCP連続して順序付けられたバイトストリームを転送するという、最も得意とする用途に使用する必要があります。それ以上でもそれ以下でもありません。メッセージ、パケット、フレームはありません。

そのような詳細を制御する必要がある場合は、下位レベルの API を検討する必要があります。SOCK_RAWとを使用できますPF_PACKET

パケット ソケットは、デバイス ドライバー (OSI レイヤー 2) レベルで raw パケットを送受信するために使用されます。

@gby は UDP について言及しましたが、これは (部分的に) 良い考えです:UDP固定サイズです。ただし、IP フラグメンテーションに対処する (または を使用するIP_DONTFRAG) 必要があることに注意してください。

于 2011-05-31T14:59:56.143 に答える
2

OPの質問の下にある私のコメントに加えて、イーサネット経由でTCP / IPを送信する方法を概説している元のRFCからのこの引用は関連しています:

RFC 894 (強調鉱山): 必要に応じて、イーサネットの最小フレーム サイズを満たすために、データ フィールドを (オクテットをゼロで) パディングする必要があります。

すべてのイーサネット フレームを最大サイズにしたい場合は、そう言ったはずです。彼らはしませんでした。

于 2011-05-31T17:30:28.157 に答える