0

I am using Tshark to start capturing with CommandLine, with the output of this process I am calculating the received packets number: my StreamReader read the output of the process and inside this output parse the packet number in order to show this number on my form. my problem is after I am kill the process there is different between the number of packets i am show and the actual packets inside the file (pcap file) so my question is if there is a way to kill the process but wait until all the process output finish.

public class Tshark
{
    public int _interfaceNumber;
    public string _pcapPath;
    public int _test;
    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.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
        _tsharkProcess1.StartInfo.RedirectStandardOutput = true;
        _tsharkProcess1.StartInfo.UseShellExecute = false;
        _tsharkProcess1.StartInfo.CreateNoWindow = true;
        _tsharkProcess1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        _tsharkProcess1.Start();

        Thread.Sleep(2000);
        DateTime lastUpdate = DateTime.MinValue;
        StreamReader myStreamReader = _tsharkProcess1.StandardOutput;

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

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

            if ((DateTime.Now - lastUpdate).TotalMilliseconds > 1000)
            {
                lastUpdate = DateTime.Now;
                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...            
    }
}
Toon Krijthe
  • 52,876
  • 38
  • 145
  • 202
falukky
  • 1,099
  • 2
  • 14
  • 34

1 Answers1

1

Instead of killing the process, close it gracefully. It's a bit much to expect something you just killed to carry on talking to you.

You'll have to come up with some way to gracefully close the process. Exactly how is best to do that, I cannot tell from here.

It might be more appropriate to use a packet capture library rather than relying on external console apps. For example pcap.net. I'm sure there are other libs for this.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Don't know. Do you have control of Tshark? No idea what that is. – David Heffernan Sep 29 '12 at 18:49
  • It's a console app right. At the console can you do anything more than CTRL+C? If not then GenerateConsoleCtrlEvent will do the same programmatically. – David Heffernan Sep 29 '12 at 18:58
  • if i want to stop capturing i need to press CTRL+C – falukky Sep 29 '12 at 20:25
  • Then calling `GenerateConsoleCtrlEvent` is equivalent. But you'd be way better off with a pcap lib. – David Heffernan Sep 29 '12 at 20:30
  • can i have example how to use it and where ? (i am a new developer...) – falukky Sep 29 '12 at 20:33
  • Did you check to see if CTRL+C does what you want? When you do that, do the standard output and the pcap file match? Why don't you just use a pcap lib? Shelling out to a separate process doesn't seem sensible. Why are you doing that? Why do you think that is better than pcap lib? – David Heffernan Sep 29 '12 at 20:38
  • I've never called `GenerateConsoleCtrlEvent` from C#. If I wanted to do so I would type those keywords into a search engine. You could easily do so too. Please do learn to use search. Anyway, when you do so you'd find this: http://stackoverflow.com/questions/297615/stuck-on-generateconsolectrlevent-in-c-sharp-with-console-apps and that tells you that you can't call `GenerateConsoleCtrlEvent` because `Process` doesn't support `CREATE_NEW_PROCESS_GROUP`. Use a pcap lib. Or live with the standard output not being flushed when you kill the process. – David Heffernan Sep 29 '12 at 20:43
  • Well, so does `Process.Kill()` – David Heffernan Sep 29 '12 at 20:44
  • what do you mean use pcap lib ? – falukky Sep 29 '12 at 20:46
  • I mean stop using Tshark. Which is an external process. And use something in your process. For example pcap .net. http://pcapdotnet.codeplex.com/ – David Heffernan Sep 29 '12 at 20:48
  • i am using pcap.net but when i save file on disk i cannot know "ongoing" the number of received packets – falukky Sep 29 '12 at 20:54
  • I think I answered the original question now. – David Heffernan Sep 29 '12 at 21:43