由于高速网络,应用程序在获取进程输出时卡住

时间:2012-09-28 14:58:28

标签: c# winforms

我有一个应用程序捕获(使用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();
}

1 个答案:

答案 0 :(得分: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时使用post增量。这将传递_packetsCount的当前值,然后在OnPacketProgress返回后递增它。你应该仔细检查这是否是你想要的。