DOBON.NET DOBON.NETプログラミング掲示板過去ログ

【C#】パケットキャプチャの動作が重い(rawソケット)

環境/言語:[Windows 7、Microsoft .NET Framework 3.5、Visual Studio 2008]
分類:[.NET]

こんにちは。
4年前、C#で以下の目的を達成するツールを書きました。

・特定のサーバへのアクセス検出したら警告を出したい
・禁止URLリストに該当するURLへの接続を発見次第、警告を出したい

このために、rawソケットを使ってパケットをキャプチャし、バルーンヘルプにて警告を出すという常駐プログラムを作成し、Windows XP環境でずっと問題なく使っていました。
ですが、Windows 7で動かしたところ、異常に動きが重くなっていることに気づきました。
きちんと警告も出るのですが、とあるサーバにアクセスしてから10秒くらいしてやっとパケットが拾える感じです。
以下のソースにおけるSocket#BeginReceive()する時点ですでに遅れている感じです。

そこでお知恵を拝借したいのですが、

・原因として考えられるものがあれば教えていただけますでしょうか。
・対応策をご存じの方はそれも教えていただけますでしょうか。

参考までに、ソースコードの抜粋を記載します。


----- ソースコード(抜粋)ここから -------------------------------------

// ソケットの生成
byte[] byTrue = new byte[4] { 1, 0, 0, 0 };
byte[] byOut = new byte[4];
socket = new Socket(
    AddressFamily.InterNetwork,
    SocketType.Raw,
    ProtocolType.IP
);

// インスタンスにオプションを設定
socket.SetSocketOption(
    SocketOptionLevel.IP,
    SocketOptionName.HeaderIncluded,
    true
);

// ソケットをアドレスとポートにバインド
socket.Bind(new IPEndPoint(IPAddress.Parse(this.IP), 15000));

// プロミスキャスモードを設定して全てのパケットを受信
socket.IOControl(
    IOControlCode.ReceiveAll,
    byTrue,
    byOut
);

// キャプチャ開始
state = new StateObject();
state.workSocket = socket;
IAsyncResult result = socket.BeginReceive(
    state.buffer,
    0,
    StateObject.BufferSize,
    0,
    new AsyncCallback(ReceiveCallback),
    state
);

/// <summary>
/// 受信用メソッド
/// </summary>
/// <param name="ar"></param>
private static void ReceiveCallback(IAsyncResult ar)
{
    // データの取得
    StateObject currentstate = (StateObject)ar.AsyncState;
    Socket currentsocket = currentstate.workSocket;
    int bytesRead = 0;
    try
    {
        bytesRead = currentsocket.EndReceive(ar);
    }
    catch (Exception ex)
    {
    }

    // 解析
    if (bytesRead > 0)
    {
        // 再取得
        try
        {
            currentsocket.BeginReceive(
                currentstate.buffer,
                0,
                10000,
                0,
                new AsyncCallback(ReceiveCallback),
                currentstate
            );
        }
        catch (SocketException sex)
        {
        }

        // IPヘッダの取り出し
        StringBuilder ipHeader = new StringBuilder();
        foreach (byte b in currentstate.buffer)
        {
            string s = b.ToString("X");
            string str2 = Convert.ToString(b, 2);
            string str3 = String.Format("{0:D8}", Convert.ToInt32(str2));
            ipHeader.Append(str3);
        }
        
        // 警告処理
    }
}
■No28618に返信(きんさんの記事)

関係ないかもしれませんがIPv6が動いているとVista,7のネットワークって
かなり遅いみたいなのです。もしかしたらそれかも。
■No28622に返信(shuさんの記事)
> ■No28618に返信(きんさんの記事)
>
> 関係ないかもしれませんがIPv6が動いているとVista,7のネットワークって
> かなり遅いみたいなのです。もしかしたらそれかも。


ありがとうございます。確認しましたが、IPv6のネットワークアダプタ自体が既に無効になっておりました。。。

DOBON.NET | プログラミング道 | プログラミング掲示板