Come implementare il ping di PsPing TCP in C #

Sto cercando di implementare lo strumento SysInternals PsPing di Mark Russinovich in C # per misurare le latenze usando il ping TCP.

Non sono sicuro di come effettui la chiamata ping (apparentemente non utilizza socket Window non funzionanti, perché non richiede i privilegi di amministratore per l’esecuzione). So che hping invia il pacchetto SYN su TCP e misura il tempo di risposta.

Quale sarebbe la tecnica di implementazione per la misurazione accurata della latenza del server che su TCP non misura i tempi di caricamento della pagina ma solo la latenza della rete per il riconoscimento del pacchetto? C’è una biblioteca per questo?

 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 

Aggiornamento: Si prega di non rispondere come “perché non si utilizza la class Ping, già fa la cosa” come sto chiedendo di ping su TCP, non ICMP.

Ho provato diversi approcci, prima pensando di usare socket grezzi o almeno di usare chiamate native, ma un semplice collegamento TCP e close sembra creare esattamente gli stessi risultati dell’utilità psping:

 var times = new List(); 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()); 

Ispezionando il traffico usando Wireshark, posso confermare che sia lo psping che lo snippet sopra stanno creando esattamente la stessa sequenza di pacchetti.

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

Uscita da psping senza riscaldamento e usando il ping TCP:

 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 

Uscita dal programma sopra:

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

Per quanto riguarda le misure, devo dire che a volte ci sono diversi risultati in diverse esecuzioni, ma nel complesso sembravano abbastanza vicini: il tipo di prove che misurano la chiamata a Connect() è abbastanza buono. Sto pensando, prendere una mediana di poche centinaia di risultati potrebbe dimostrarlo con un po 'più di confidenza.

Winsock ti permetterà sicuramente di farlo facilmente.

Hai guardato alla fonte di programmi come http://www.elifulkerson.com/projects/tcping.php ?

Programma abbastanza semplice (console) che fa esattamente quello che vuoi (AFAIK), e fornito di codice sorgente che sembra essere molto chiaro, breve e facile da leggere (anche per programmatori non c ++, non ho praticato C ++ da un po ‘ e nonostante ciò ho trovato molto piacevole da leggere).

Puoi costruirlo e eseguirne il debugging con VS per trovare rapidamente ciò che desideri. Dovrebbe essere facile ottenere le poche chiamate API Win32 coinvolte nel ping TCP. In questo modo, puoi facilmente convertire la parte interessante in C # o incorporarla in una DLL gestita.

Basta testare prima se fa esattamente quello che vuoi.

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