24

I'm using this code but when i stop the process it not get the ping statistics :

System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "ping";
p.StartInfo.Arguments = "-c " + count + " -i " + interval + " -s " + buffer + " -W " + timeout + " " + address;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;

string readData = "";

DateTime dt = DateTime.Now.AddSeconds(5);
if (p.Start())
{
    Scanner scanner = new Scanner(p.StandardOutput.BaseStream);

    while (scanner.HasNextLine)
    {
        readData =  scanner.NextLine().ToString();
        Console.WriteLine(readData.ToString());

        if (!string.IsNullOrEmpty(readData) && !readData.StartsWith("---"))
        {
            Match M = Regex.Match(readData, @"^[\d]+ bytes from ([^:]+): [^ ]+ ttl=([\d]+) time=([^ ]+) ms");

            if (M != null && M.Success)
            {
                string IP = M.Groups[1].Value;
                string TTL = M.Groups[2].Value;
                string timeStr = M.Groups[3].Value;

                Console.WriteLine(String.Format("Ping to {0} took {2} ms with a ttl of {1}", IP, TTL, timeStr));
                // Parsing the timeStr will work the same way as above
               if(dt > DateTime.Now)
               {
                   p.StandartInput.Write("\x3");
                }
            }
            else
            {
                Match M1 = Regex.Match(readData, @"^rtt [^0-9]*([\d][^\/]+)\/([^\/]+)\/([^\/]+)\/([^ ]+) ms$");

                if (M1 != null && M1.Success)
                {
                    float avgPingTime = 0;
                    float maxPingTime = 0;
                    float minPingTime = 0;

                    string minPingString = M1.Groups[1].Value;
                    string avgPingString = M1.Groups[2].Value;
                    string maxPingString = M1.Groups[3].Value;

                    // Now parse that value
                    float.TryParse(minPingString, System.Globalization.NumberStyles.Float, System.Globalization.NumberFormatInfo.InvariantInfo, out minPingTime);
                    float.TryParse(avgPingString, System.Globalization.NumberStyles.Float, System.Globalization.NumberFormatInfo.InvariantInfo, out avgPingTime);
                    float.TryParse(maxPingString, System.Globalization.NumberStyles.Float, System.Globalization.NumberFormatInfo.InvariantInfo, out maxPingTime);

                    Console.WriteLine(String.Format("Min Time : {0} , AVG {2} ms, Max Time {1}", minPingTime, maxPingTime, avgPingTime));
                }
            }
        }
    }
}

Without using

if(dt > DateTime.Now)
{
     p.StandartInput.Write("\x3");
}

the result display like this :

64 bytes from 8.8.8.8: icmp_req=1 ttl=46 time=13.9 ms
64 bytes from 8.8.8.8: icmp_req=2 ttl=46 time=13.9 ms
64 bytes from 8.8.8.8: icmp_req=3 ttl=46 time=13.9 ms

--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 3016ms
rtt min/avg/max/mdev = 13.910/13.926/13.951/0.010 ms

but if I stop the ping using p.StandartInput.Write("\x3"); it never goes to the statistics part it hangs at sequence 1 : 64 bytes from 8.8.8.8: icmp_req=1 ttl=46 time=13.9 ms and dont continue reading , how to show the statistics after stoping the ping process ?

in other words my problem is when the user want to stop the ping it should display the statistics for the certain time that it was used to ping...

UPDATE

I have implemented p.StandartInput.Write("/x3"); and it interrupts the ping process but it does not display the statistics and just hangs there.

EAK TEAM
  • 5,726
  • 4
  • 30
  • 52
  • 1
    Write a `Ctrl-C` to your std input stream, in hex it is `3`, so `Write("\x3")` – SushiHangover Mar 20 '17 at 14:43
  • i have tried in `adb shell ping -c 3 8.8.8.8` with a CTRL+C but it just stop imediately , it don't show the statistics part ... – EAK TEAM Mar 20 '17 at 14:45
  • Just tried it and it produces the statistics lines... since you are testing via `adb`, actually shell in first `adb shell` and then run `ping` and then `Ctrl-C`, you are Ctrl-C/aborting the adb process not the ping process – SushiHangover Mar 20 '17 at 14:47
  • It seems that if you call ```p.Exit()``` the ```StandardOutput``` gets locally closed too. Try defining the ```Exited``` before your loop. If your process gets killed this event will get raised. Try getting the latest output of the process (which is passed to the event as the ```sender```). – ClemensGerstung Mar 20 '17 at 14:48
  • `adb shell`, then `ping 8.8.8.8` and then `Ctrl-C` to abort the `ping`, and the stats will be displayed, It also works from Process, as I use `ping` in a couple of my apps.... – SushiHangover Mar 20 '17 at 14:50
  • @HumpaLumpa007 , `adb shell` when im trying CTRL+C is not produces the statistics too when i stop the process (The terminal not closed in that way ) , why you think that in the code it will produce the statistics ? – EAK TEAM Mar 20 '17 at 14:51
  • @SushiHangover , yes you are right. Firstly `adb shell` than the ping request. Add it as answer how to implement in the code i will accept as solved.. thanks it works in this way – EAK TEAM Mar 20 '17 at 14:53
  • @SushiHangover , i have a last prob here , it stops the ping but not continuing reading the statistics.. i have updated my question too ... – EAK TEAM Mar 20 '17 at 17:13
  • Try to read StandardError property of the process just like StandardOutput. – Mahdi Ataollahi Apr 09 '17 at 09:04
  • Check this http://stackoverflow.com/questions/8808663/get-live-output-from-process – Bali C Apr 10 '17 at 11:08

1 Answers1

1

If you are actually interested in the ping values, why not just use the ping class? https://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping(v=vs.110).aspx

Neil
  • 11,059
  • 3
  • 31
  • 56
  • Because ping from Android System is better than Mono Framework , i have tried before and noticed that Round Trip Time is highter in MONO because of Sand Box .... It it not working as excepted ! And it have some bugs in IPStatus.TtlExpired . – EAK TEAM Mar 28 '17 at 13:08
  • If you are that concerned about the speed of the ping, why not write your own ICMP service? Shelling out to perform that sort of function might be OK on a Linux system, but on a mobile/Xamarin, I'm not sure that is the correct answer to your problem. – Neil Mar 29 '17 at 08:44
  • why to write my own ICMP service ? I dont understand what you mean. The question is how to stop the process after it started via std exec. – EAK TEAM Mar 29 '17 at 11:02
  • 1
    I believe, stopping the ping command is a 'solution' to your problem, but your problem actually seems to be 'how to measure ping times between your device and some IP address'. If measuring round trip times is actually your problem, then writing your own ICMP service (which is what PING uses) would solve your problem. – Neil Mar 29 '17 at 12:36
  • 1
    I think you dont understand well what i asked for. I get the time and everything else very good. The problem is not that ! – EAK TEAM Mar 29 '17 at 13:47