1

WinDDK をダウンロードし、ndisprot 5x を使用してユーザー アプリから raw イーサネット パケットをブロードキャストし、宛先 MAC をすべて 0xff に指定しています。大規模で反復的なデータ セットでは、あまり生産的ではないようです。

現在うまく機能しているのはループバックです。宛先と送信元のMACを自分のものとして指定すると、必要な速度が得られますが、パケットはネットワークカードから離れることはありません。

いくつかの ndis ドライバー オプションが不足していて、このサンプル MS ドライバーを使用してブロードキャストが完了するのを待っている可能性がありますか? 私が望むのは、パケットがネットワークにブロードキャストされることだけであり、配信ステータスはあまり気にせず、できるだけ早くそれを取り除きたい.

ここで 2 ポイントしかないシステムは役に立ちますか? 何がラグを引き起こしているのかわかりません。

4

1 に答える 1

1

カーネル モードで送信完了パスを削除することはできません。その理由は、最終的に送信完了を発行するまで、ネットワーク カードがメモリからバイトを読み取るのにビジーであるためです。パケットを再利用する前に送信完了を待たなかった場合、ネットワーク カードは完全なパケットを読み取る機会がありませんでした。破損したデータを送信することになります。

しかし、在庫の NDISPROT サンプルを使用して大量のデータを送信すると、効率が大幅に低下することは間違いありません。問題は、NDISPROT のユーザーモード サンプル アプリケーションがデータをカーネルモードに同期的に書き込むことです。つまり、スレッドは書き込み (パケットの送信) を開始し、書き込み (パケットの送信) が完了するまでブロックします。(NDISPROT サンプルの目的は、カーネル モードで NDIS と相互運用する方法を説明することであり、ユーザーとカーネルの通信に関する複雑な手法を説明することではないため、このサンプルは非効率的です)。

複数のデータを同時に発行するいくつかの手法のいずれかを使用すると、これを大幅に高速化できます。

  1. マルチスレッドを使用します。複数のスレッドで並行して行うことを除いて、今行っているのと同じことを行います。これは非常に簡単に設定できますが、スケーリングがうまくいきません (トラフィックを 10 倍にスケーリングするには、10 倍のスレッドが必要であり、キャッシュの問題が発生し始めます)。さらに、データセットを順番に送信する必要がある場合は、スレッドがリクエストを順番に発行できるようにするために、一連の複雑な同期が必要になります。

  2. WriteFile および OVERLAPPED データ構造で非同期呼び出しを使用します。これには、ユーザーモード アプリでいくつかのツールを変更する必要があります。(幸い、カーネル ドライバーは既にサポートされているため、カーネル ドライバーに触れる必要はありません)。OVERLAPPED 書き込みを使用すると、1 つのスレッドから複数の同時書き込みを発行し、それらのいずれか (またはすべて) が完了したときに通知を受け取ることができます。重複する設計に十分注意すれば、100Mbps のネットワーク リンクを簡単に埋めることができるはずです。

より明確にするために、これはあなたが現在持っているものです:

Your app           NDISPROT driver         Network card         The network
---------------------------------------------------------------------------------
  WriteFile
   .      \-------> NdisProtWrite
   .                            \-------> NdisSendPackets
   .                                            |
   .                                   (copy packet payload
   .                                    from system RAM to
   .                                    network card's buffer)
   .                                            |
   .                                            |---------------> Start sending
   .             NdisProtSendComplete <---------|                      .
  WriteFile <----/                              |                      .
   returns                                      |<--------------- Finish sending

ご覧のとおり、ユーザー モード アプリは、ネットワーク カードが RAM から NIC ハードウェアにパケット ペイロードをコピーしている間ずっと、WriteFile でスタックしています。代わりに、kernelmode への非同期書き込みを使用すると、次のようになります。

Your app           NDISPROT driver         Network card         The network
---------------------------------------------------------------------------------
  WriteFile
   .      \-------> NdisProtWrite
   .               |            \-------> NdisSendPackets
  WriteFile <------/                           |
   returns                              (copy packet payload
                                        from system RAM to
                                        network card's buffer)
                                                |
                                                |---------------> Start sending
                 NdisProtSendComplete <---------|                      .
  Async write <--/                              |                      .
   completes                                    |<--------------- Finish sending

このセットアップでは、WriteFile がより迅速に返されるため、NIC がまだ最初のパケットを読み取っている間に、別のパケット (または 10) をキューに入れる機会があります。通常の OVERLAPPED 手法のいずれかを使用して、書き込み (パケットの送信) がいつ完了したかを判断し、データ バッファーを再利用できます。

非同期 I/O の使用を開始するには、このドキュメントから始めてください。(おっと、彼らの図は私の素晴らしい ASCII アートから 90° 回転しているように見えます...)。

于 2011-07-09T02:04:58.653 に答える