2014-09-26 11 views
5

Ich versuche Mark Russinovich SysInternals PsPing tool in C# zu implementieren Latenzen mit TCP-Ping zu messen.Wie zu implementieren PsPing TCP-Ping in C#

Ich bin mir nicht sicher, wie es den Ping-Aufruf (anscheinend keine rohen Window-Sockets verwendet, da es keine Administratorrechte zum Ausführen benötigt). Ich weiß, hping sendet SYN-Paket über TCP und misst Antwortzeit.

Was wäre die Implementierungstechnik für die genaue Messung der Serverlatenz, die über TCP nicht die Seitenladezeiten, sondern nur die Netzwerklatenz für die Paketbestätigung misst? Gibt es dafür eine Bibliothek?

C:\>psping stackoverflow.com:80 

PsPing v2.01 - PsPing - ping, latency, bandwidth measurement utility 
Copyright (C) 2012-2014 Mark Russinovich 
Sysinternals - www.sysinternals.com 

Pinging 198.252.206.16 with 32 bytes of data: 
5 iterations (warmup 1) ping test: 
Reply from 198.252.206.16: 81.57ms 
Reply from 198.252.206.16: 80.81ms 
Reply from 198.252.206.16: 80.68ms 
Reply from 198.252.206.16: 80.52ms 
Reply from 198.252.206.16: 80.71ms 

Ping statistics for 198.252.206.16: 
    Sent = 4, Received = 4, Lost = 0 (0% loss), 
    Minimum = 80.52ms, Maximum = 80.81ms, Average = 80.68ms 

Update: Bitte antworten Sie nicht wie „warum Sie nicht Ping-Klasse verwenden, ist es bereits tut das Ding“, wie ich über Ping über TCP bin gefragt, nicht ICMP.

+1

Viele Sysinternals-Tools verwenden nicht dokumentierte Systemaufrufe. Es ist unwahrscheinlich, dass Sie eine leicht zu verweisende Quelle finden, die sagt, wie es funktioniert, ganz zu schweigen davon, wie Sie das Gleiche mit C# tun können. –

+0

@ScottChamberlain nur ausprobieren vielleicht gibt es eine Methode, die ich nicht kenne. –

+0

@ahmetalpbalkan: Was ist mit Ping-Klasse, mit der Sie einen Server oder interne IP-Ping-und Sie können die Wiedergabe Zeit bekommen? http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping%28v=vs.110%29.aspx – houssam

Antwort

14

ich verschiedene Ansätze versucht haben, erste Denk ich Raw Sockets oder zumindest verwenden nativen Anrufe verwenden musste, aber eine einfache TCP verbinden und schließen genau die gleichen Ergebnisse wie die psping zu schaffen scheint Dienstprogramm:

var times = new List<double>(); 
for (int i = 0; i < 4; i++) 
{ 
    var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    sock.Blocking = true; 

    var stopwatch = new Stopwatch(); 

    // Measure the Connect call only 
    stopwatch.Start(); 
    sock.Connect(endPoint); 
    stopwatch.Stop(); 

    double t = stopwatch.Elapsed.TotalMilliseconds; 
    Console.WriteLine("{0:0.00}ms", t); 
    times.Add(t); 

    sock.Close(); 

    Thread.Sleep(1000); 
} 
Console.WriteLine("{0:0.00} {1:0.00} {2:0.00}", times.Min(), times.Max(), times.Average()); 

inspizieren des Verkehrs mit Wireshark kann ich sowohl psping und das snippet oben schaffen genau die gleiche Sequenz von Paketen bestätigen.

-> [SYN] 
<- [SYN,ACK] 
-> [ACK] 
-> [FIN,ACK] 
<- [FIN,ACK] 
-> [ACK] 

Ausgabe von psping ohne Aufwärm- und TCP-Ping mit:

C:\>psping -w 0 stackoverflow.com:80 

PsPing v2.01 - PsPing - ping, latency, bandwidth measurement utility 
Copyright (C) 2012-2014 Mark Russinovich 
Sysinternals - www.sysinternals.com 

TCP connect to 198.252.206.16:80: 
4 iterations (warmup 0) connecting test: 
Connecting to 198.252.206.16:80: 92.30ms 
Connecting to 198.252.206.16:80: 83.16ms 
Connecting to 198.252.206.16:80: 83.29ms 
Connecting to 198.252.206.16:80: 82.98ms 

TCP connect statistics for 198.252.206.16:80: 
    Sent = 4, Received = 4, Lost = 0 (0% loss), 
    Minimum = 82.98ms, Maximum = 92.30ms, Average = 85.43ms 

Ausgabe aus dem Programm über:

C:\>TcpPing.exe stackoverflow.com 80 
88.60ms 
83.65ms 
84.05ms 
84.05ms 
83.65 88.60 85.09 

Wie für Messungen, muss ich sagen, manchmal gibt Es gibt ziemlich viele verschiedene Ergebnisse bei verschiedenen Läufen, aber insgesamt schienen sie ziemlich nah zu sein: irgendwie beweist das Messen der Connect() Anruf ist gut genug. Ich denke, ein Median von ein paar hundert Ergebnissen könnte es mit ein bisschen mehr Vertrauen beweisen.

+1

Ausgezeichnet für mich gearbeitet! Es reflektiert auch sehr enge Ergebnisse zu 'psping'. Vielen Dank, sehr verdient. –

+0

Die EndPoint-Klasse ist etwas unhandlich, daher bevorzuge ich die IPAddress-Klasse und einen Port. Um dies zu tun: IPAddress ip = Dns.GetHostEntry ("www.google.com.au"). AddressList [0]; int Port = 443; und dann sock.Connect (ip, port); –

1

Winsock wird Ihnen sicherlich erlauben, dies leicht zu tun.

Haben Sie Quellcode von Programmen wie http://www.elifulkerson.com/projects/tcping.php betrachtet?

Ziemlich einfach Programm (Konsole), die genau das tut, was Sie wollen (AFAIK), und mit Quellcode zur Verfügung gestellt, die sehr klar, kurz und leicht zu lesen ist (auch für nicht C++ - Programmierer habe ich nicht geübt C++ seit einer Weile und trotz allem fand ich es sehr schön zu lesen).

Sie können es bauen und debuggen mit VS, um schnell zu finden, was Sie wollen. Es sollte einfach sein, die wenigen Win32-API-Aufrufe zu erhalten, die an TCP-Ping beteiligt sind. Auf diese Weise können Sie den interessanten Teil auf einfache Weise in C# konvertieren oder in eine verwaltete DLL einbetten.

Testen Sie einfach vorher, wenn es genau das tut, was Sie wollen.

Quelle Link: http://www.elifulkerson.com/projects/downloads/tcping-0.23/tcping-src.zip