1

我有应用程序如何打开 Tshark 进程并开始捕获数据包,该进程在磁盘上创建 pcap 文件,并从我的主窗体中检查此类属性并更新我的 GUI。

最近我添加了检查磁盘上的文件大小并且此属性不断增长的选项,我的问题是,在我启动我的函数后,代表文件大小的属性尝试检查此文件,但如果进程没有创建文件然而这个属性是空的,我的应用程序崩溃了,所以我添加了 Thread.Sleep 现在它正在工作,但我想知道是否有击球手的方式来做到这一点。

这是我的类,具有开始捕获的函数,我正在谈论的属性是 _myFile,我想要更改的 Thread.Sleep 在我的 tshark.Start();

    public class Tshark2
    {
        #region class members
        public string _tshark;
        public string _filePath;
        public List<string> _list;
        public ProcessStartInfo _process;
        public myObject _obj;
        public int _interfaceNumber;
        public string _pcapPath;
        public string _status;
        public int _receivesPackets;
        public int _packetsCount;
        public string _packet;
        public double _bitsPerSecond;
        public double _packetsPerSecond;
        public decimal _packetLimitSize;
        public DateTime _lastTimestamp;
        PacketDevice _device;
        public delegate void dlgPackProgress(int progress);
        public event dlgPackProgress evePacketProgress;
        public DirectoryInfo _directoryInfo;
        public FileInfo _myFile;
        public FileInfo _fileInfo;
        public FileInfo[] _dirs;
        public long _fileSize;

        public void startCapturing()
        {
            _status = "Listening...";
            ThreadStart tStarter = delegate { openAdapterForStatistics(_device); };
            Thread thread = new Thread(tStarter);
            thread.IsBackground = true;
            thread.Start();

            Process tshark = new Process();
            tshark.StartInfo.FileName = _tshark;
            tshark.StartInfo.Arguments = string.Format(" -i " + _interfaceNumber + " -V -x -s " + _packetLimitSize + " -w " + _pcapPath);
            tshark.StartInfo.RedirectStandardOutput = true;
            tshark.StartInfo.UseShellExecute = false;
            tshark.StartInfo.CreateNoWindow = true;
            tshark.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            tshark.Start();
            Thread.Sleep(1000);
            DateTime lastUpdate = DateTime.MinValue;
            StreamReader myStreamReader = tshark.StandardOutput;
            _fileInfo = new FileInfo(_pcapPath);
            string directoryName = _fileInfo.DirectoryName;
            _directoryInfo = new DirectoryInfo(directoryName);
            _dirs = _directoryInfo.GetFiles();
            _myFile = _dirs.FirstOrDefault(f => f.Name.Equals(_fileInfo.Name));

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

                if (_packet.StartsWith("    Frame Number:"))
                {
                    string[] arr = _packet.Split(default(char[]), StringSplitOptions.RemoveEmptyEntries);
                    _receivesPackets = int.Parse(arr[2]);
                    _packetsCount++;
                }

                if ((DateTime.Now - lastUpdate).TotalMilliseconds > 1000)
                {
                    lastUpdate = DateTime.Now;
                    OnPacketProgress(_packetsCount++);
                }
            }

            tshark.WaitForExit();
        }
}
4

1 回答 1

0

尝试 Process.WaitForExit 而不是固定的睡眠时间。请参阅http://msdn.microsoft.com/en-us/library/ty0d8k56.aspx

编辑:WaitForExit 应该在读取您正在生成的进程的输出之前进行,如果您试图利用该进程的输出。在这种情况下,WaitForExit 将取代 Thread.Sleep。如果要在写入时监视文件大小,请等待文件创建完成,然后使用计时器检查文件写入的进度。请参见下面的示例。

for (int i = 20 /* seconds till exception */; i > 0; i--)
{
    if (File.Exists(_pcapPath))
        break;
    else if (i == 1)
        throw new Exception("File was not created within 20 seconds.");
    else
        Thread.Sleep(1000);
}

while (!tshark.WaitForExit(1000 /* file size update interval */))
{
    var fileInfo = new FileInfo(_pcapPath);
    Console.WriteLine("File has grown to {0} bytes", fileInfo.Length);
}

Console.WriteLine("Complete");
于 2012-10-06T20:50:52.057 回答