ネットワーク アクセスが必要な仮想化アプリケーションを C# で開発しています。ndisprot サンプル ドライバーを使用して、イーサネット レイヤー 2 パケットの読み取りと書き込みを行っています。WriteFile 操作に膨大な時間がかかることを除いて、すべて正常に動作しています。通常は 300 ~ 800 ミリ秒ですが、書き込みが完了するまでに数秒かかる場合があります。
これは、イーサネット パケットをドライバーに書き込む C# 関数です。ストップウォッチを使用して、所要時間を測定しています。
private Stopwatch sw = new Stopwatch();
/// <summary>
/// Writes a layer-2 Ethernet packet to the adapter
/// </summary>
/// <param name="packet">The packet data</param>
/// <returns>true if the write was successful</returns>
public bool WriteEnetPacket(byte[] packet)
{
int bytesSent = 0;
bool packetSent = false;
// Copy the packet data to raw buffer
IntPtr packetPtr = Marshal.AllocHGlobal(packet.Length);
Marshal.Copy(packet, 0, packetPtr, packet.Length);
sw.Restart();
packetSent = WriteFile(this.handle,
packetPtr,
packet.Length,
out bytesSent,
0);
sw.Stop();
Console.WriteLine("WriteFile completed in {0}ms", sw.Elapsed.Milliseconds);
// Free the memory
Marshal.FreeHGlobal(packetPtr);
// check to see if packet was sent
if (!packetSent)
{
var err = UnsafeMethods.GetLastError();
var errStr = UnsafeMethods.GetLastErrorString();
Console.WriteLine("ERROR: Packet not sent: 0 bytes written.");
Console.WriteLine("Reason: " + errStr);
return false;
}
// otherwise the packet was sent
Console.WriteLine("Packet sent: " + bytesSent.ToString() + "bytes written");
return true;
}
アプリケーションを実行すると、出力は次のようになります。有線接続しています。
Packet sent: 42bytes written
WriteFile completed in 160ms
Packet sent: 42bytes written
WriteFile completed in 458ms
Packet sent: 74bytes written
WriteFile completed in 364ms
Packet sent: 74bytes written
WriteFile completed in 51ms
Packet sent: 86bytes written
WriteFile completed in 221ms
Packet sent: 74bytes written
WriteFile completed in 271ms
Packet sent: 74bytes written
WriteFile completed in 1ms
Packet sent: 74bytes written
WriteFile completed in 292ms
アプリケーションに ping を実行すると、応答時間は WriteFile の完了にかかる時間とほぼ一致するため、ハングアップがドライバーのどこかにあることがわかります。これを高速化するためにサンプル ドライバーでできることはありますか? 私は何を間違っていますか?
編集: 今日、内蔵アダプターの代わりに USB-Ethernet アダプターを使用してみましたが、パフォーマンスがさらに低下しました! 書き込みが完了するまでに 15 ~ 30 秒かかります。読み取りはほぼ瞬時に行われるため、これは非常に奇妙です。
Edit2: 私のドライバーには、読み取りスレッドと書き込みスレッドの 2 つのスレッドがあります。リーダースレッドを無効にすると、書き込みが即座に完了するようです。ファイルからの読み取りがファイルへの書き込みに影響するのはなぜですか?