Как реализовать PSPING TCP ping в C#

Я пытаюсь реализовать SysInternals Марка Русиновича инструмент PsPing В C# для измерения задержек с использованием TCP ping.

Я не уверен, как он делает вызов ping (по-видимому, не использует необработанные сокеты окон, потому что для запуска не требуются права администратора). Я знаю hping отправляет пакет SYN по TCP и измеряет время отклика.

каким будет метод реализации для точного измерения задержки сервера, который по TCP не измерьте время загрузки страницы, но только сетевую задержку для подтверждения пакета? Для этого есть библиотека?

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: пожалуйста, не отвечайте, как "почему бы вам не использовать класс Ping, он уже делает это", поскольку я спрашиваю о ping через TCP, а не ICMP.

2 ответов


я попробовал несколько подходов, сначала подумав, что мне нужно использовать необработанные сокеты или, по крайней мере, использовать собственные вызовы, но простое TCP-соединение и закрытие, похоже, создают точно такие же результаты, как утилита psping:

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());

проверяя трафик с помощью Wireshark, я могу подтвердить, что psping и приведенный выше фрагмент создают точно такую же последовательность пакетов.

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

выход из psping без разогрева и с использованием TCP ping:

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

выход из выше программа:

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

Что касается измерений, я должен сказать, иногда есть довольно много разных результатов на разных прогонах, но в целом они казались довольно близкими: вид доказывает измерение Connect() звонок достаточно хорошо. Я думаю, что медиана из нескольких сотен результатов может доказать это с большей уверенностью.


Winsock, безусловно, позволит вам сделать это легко.

вы посмотрите на источник программы, как http://www.elifulkerson.com/projects/tcping.php ?

довольно простая программа (консоль), которая делает именно то ,что вы хотите (AFAIK), и снабжена исходным кодом, который выглядит очень четким, коротким и легким для чтения (даже для не программистов на c++, я не практиковал C++ с тех пор, и, несмотря на это, я нашел его очень приятным читать.)

вы можете построить его и отладить его с VS, чтобы быстро найти то, что вы хотите. Должно быть легко получить там несколько вызовов Win32 API, участвующих в TCP Ping. Таким образом, вы можете легко преобразовать интересную часть в C# или встроить ее в управляемую DLL.

просто проверьте, делает ли он именно то, что вы хотите.

исходная ссылка:http://www.elifulkerson.com/projects/downloads/tcping-0.23/tcping-src.zip