3

私は、TCPの代わりに、信頼性の高いコネクション型通信を提供する、UDP上で実行される疑似トランスポート層ソフトウェアに取り組んでいます。ネットワーク効率を最大化するために、初期化時に「最良の」ネットワークアダプタのMTUを照会します。

MIB_IFROW row = {0};
row.dwIndex = dwBestIfIndex;

dwRes = GetIfEntry(&row);

オンラインで検索すると、次のnetshコマンドを使用して、コマンドプロンプト(C ++ APIではない)から同じ値を照会できることがわかりました。

netsh interface ipv4 show interfaces
netsh interface ipv4 show subinterfaces

厄介な問題は、row.dwMtuが1500に設定されている場合でも、送信側のラップトップでネットワークトラフィックをスヌーピングすると、パケットが1300バイトのパケットに断片化されていることを示します。netshは、MTUが1300であることも報告しています。

明らかに、netshコマンドによって報告された値は実際に使用された値です。netshと同じ値を取得するために呼び出すことができるAPIを知っている人はいますか?

4

1 に答える 1

3

ローカルMTUサイズとパスMTUがあります(RFC 1191を参照)。次のようなコマンドを使用できます

ping -f -l 1464 www.stackoverflow.com
ping -f -l 1465 www.stackoverflow.com

パスMTUを決定します。ICMPパッケージとIPヘッダーのヘッダーサイズを考慮してください。APIソリューションについては、PathMTUDiscoveryを参照してください。

更新:そのような質問はもうしないでください!答えを見つけるのは私にとって非常に興味深く、私はこれに数時間を費やしました。しかし...私は見つけました!MTUサイズの正しい値を受け取るには、構造体の配列を持つ構造体をGetIpInterfaceTable返すAPIを使用する必要があります。IPインターフェースを識別するのに役立つ帽子は、他のよく知られているIPヘルパー関数と同じです。関数を使用して、別のフィールドからインターフェイス名を受け取ることもできます。PMIB_IPINTERFACE_TABLEMIB_IPINTERFACE_ROWMIB_IPINTERFACE_ROWInterfaceIndexConvertInterfaceLuidToNameWInterfaceLuid

しかし、最も興味深いのはNlMtuフィールドです

typedef struct _MIB_IPINTERFACE_ROW {
    ADDRESS_FAMILY Family;
    NET_LUID InterfaceLuid;
    NET_IFINDEX InterfaceIndex;
    // ...
    ULONG NlMtu;
    // ...
};

ドキュメント(http://msdn.microsoft.com/en-us/library/aa814496(v=VS.85).aspxを参照)では、「ネットワーク層のMTUサイズ(バイト単位)」と説明されています。同じテキストで、Windows Driver Kitのドキュメントにもありません(http://msdn.microsoft.com/en-us/library/ff559254(VS.85).aspxを参照)。このフィールドNlMtuはあなたが探しているものです。たとえば、私のコンピュータはDSLルーターを介してインターネットに接続されており、ルーターNlMtuがない場合のように1500ではありませんが、代わりに正しい値1492があります。あなたの場合、それは1300でなければなりません。

Microsoft SDKの最新バージョンのいずれかがインストールされている場合は、C:\ Program Files \ Microsoft SDKs \ Windows \ v7.0 \ Samples \ netds \ iphelp\NetinfoGetIpInterfaceTableディレクトリにAPIを使用する例があります。netinfo.cファイルの約270行にブレーキポイントを設定するだけで、対応するインターフェイスアダプタのIPMTUInterfaceTable->Table[i].NlMtuの正しい値が表示されます。レジストリでHKEY_LOCAL_MACHINE\SYSTEM \ CurrentControlSet \ services \ Tcpip \ Parameters \ Interfaces {34407201-997C-41FF-9EBF-1B7D6DF92B38}を確認した場合、インターフェイスカードのMTU REG_DWORD({34407201-997C-41FF-9EBF-1B7D6DF92B38)私の場合)それは同じ値でなければなりません。

この関数GetIpInterfaceTableはVista以降に存在しますが、名前PMIB_IPINTERFACE_TABLEから値を確認するには、TCPアダプターのMIB情報から取得します(Windows DDK)を参照してください。数年前はIPヘルパーDLLはまったくなく、IpConfig.exeを表示する情報を受け取るには、CreateFileとDeviceIoControlを使用してTCP TDIドライバーからそのような情報を提供する必要があります(L "\ Device\Tcp"やIOCTL_TCP_QUERY_INFORMATION_EXなどの定数を参照してください。 tcpioctl.h)。したがって、Windows XPでも同じ情報を提供することは可能かもしれませんが、それは重要ではありません。

于 2010-05-07T18:07:04.643 に答える