0

パケットを (wireshark を使用して) キャプチャするアプリケーションがあり、進行中の受信パケット数をフォームに表示するオプションが必要です。

コード:

public class Tshark
{
    public int _interfaceNumber;
    public string _pcapPath;
    public int _packetsCount;
    public string _packet;
    public delegate void dlgPackProgress(int progress);
    public event dlgPackProgress evePacketProgress;

    public Tshark(int interfaceNumber, string pcapPath)
    {
        _interfaceNumber = interfaceNumber;
        _pcapPath = pcapPath;
    }

    public void startTheCapture()
    {
        Process _tsharkProcess1 = new Process();
        _tsharkProcess1.StartInfo.FileName = @"C:\Program Files\Wireshark\tshark.exe";
        _tsharkProcess1.StartInfo.Arguments = string.Format(" -i " + _interfaceNumber + " -V -x -w " + _pcapPath);
        //_tsharkProcess1.StartInfo.Arguments = string.Format(" -i " + _interfaceNumber + " -c " + int.MaxValue + " -w " + _pcapPath);
        _tsharkProcess1.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
        _tsharkProcess1.StartInfo.RedirectStandardOutput = true;
        _tsharkProcess1.StartInfo.UseShellExecute = false;
        _tsharkProcess1.StartInfo.CreateNoWindow = true;
        _tsharkProcess1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        _tsharkProcess1.Start();

        StreamReader myStreamReader = _tsharkProcess1.StandardOutput;

        while (!myStreamReader.EndOfStream)
        {
            _packet = myStreamReader.ReadLine();

            //if (_packet.StartsWith("Frame Number: "))
            //{
            //    string[] arr = _packet.Split(' ');
            //    _test = int.Parse(arr[2]);
            //    _packetsCount++;
            //}

            OnPacketProgress(_packetsCount++);
        }

        _tsharkProcess1.WaitForExit();
    }

    private void OnPacketProgress(int packet)
    {
        var handler = evePacketProgress;
        if (handler != null)
        {
            handler(packet);
        }
    }

    public void killProcess()
    {
        foreach (Process prc in System.Diagnostics.Process.GetProcessesByName("tshark"))
        {
            prc.Kill();
            prc.WaitForExit();
        }
    }

    private void process_OutputDataReceived(object sender, DataReceivedEventArgs arg)
    {
        string srt = arg.Data; //arg.Data contains the output data from the process...            
    }
}

このクラスは Tshark を開始し、メイン フォームからのキャプチャを開始します。フォームにパケット数を表示するためにクラス プロパティをサンプリングするこの ProgressChanged があります。問題は、たとえば、ネットワークの速度が高い場合 (BitTorrent のダウンロード) ) フォームが動かなくなりました。数秒ごとにクラス プロパティをサンプリングすることで、これを解決できるでしょうか?

private void bgWSniffer_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    tshark = e.UserState as Tshark;
    lbl.Text = tshark._packetsCount.ToString();
    lbl.Text = tshark._packet;
}

問題のある行は OnPacketProgress(_packetsCount++); であることはわかっています。

キャプチャを開始する私の開始ボタン:

private void btnStartCapture_Click(object sender, EventArgs e)
{
    lblStatusSnifferTab2.Text = "Listening on ip address " + lblIpAddressSnifferTab2.Text;
    timerSniffer.Start();
    btnStartTabSniffer.Enabled = false;
    btnStopTabSniffer.Enabled = true;
    groupBoxSelectTabSniffer.Enabled = false;
    groupBoxOptionsSnifferTab.Enabled = false;
    groupBoxCaptureFilesTabSniffer.Enabled = false;
    groupBoxStopCaptureSnifferTab.Enabled = false;
    bgWorker = new BackgroundWorker();
    bgWorker.WorkerReportsProgress = true;
    bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWSniffer_ProgressChanged);
    bgWorker.DoWork += new DoWorkEventHandler(
        (s3, e3) =>
        {
            tshark = new Tshark(2, pcapFilePathSniffer);                    

            tshark.evePacketProgress += new Tshark.dlgPackProgress(
                (packet) =>
                {
                    bgWorker.ReportProgress(packet, tshark);
                });

            tshark.startTheCapture();
        });

    bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
        (s3, e3) =>
        {
            groupBoxSelectTabSniffer.Enabled = true;
            groupBoxCaptureFilesTabSniffer.Enabled = true;
        });

    bgWorker.RunWorkerAsync();
}
4

1 に答える 1

1

1つの解決策は次のとおりです(ミリ秒を使用して微調整できるようにします。必要な場合はTotalSecondsを使用できます):

    DateTime lastUpdate = DateTime.MinValue;

    while (!myStreamReader.EndOfStream)
    {
        _packet = myStreamReader.ReadLine();

        //if (_packet.StartsWith("Frame Number: "))
        //{
        //    string[] arr = _packet.Split(' ');
        //    _test = int.Parse(arr[2]);
        //    _packetsCount++;
        //}

        // If more than one second
        if((DateTime.Now - lastUpdate).TotalMilliseconds > 1000)
        {
            lastUpdate = DateTime.Now;
            OnPacketProgress(_packetsCount++);
        }
    }

また、私が気づいたことは、OnPacketProgress を呼び出すときにポスト インクリメントを使用することです。これにより、_packetsCount の現在の値が渡され、OnPacketProgress が返された後にインクリメントされます。それがあなたが望むものであるかどうかを再確認する必要があります。

于 2012-09-28T15:03:33.753 に答える