| Už kolikrát jsem potřeboval změřit latency, nebo round-trip-time (RTT) pro nějaký TCP server. To je ta informace v milisekundách (ms), kterou normálně vidíte, pokud děláte ping. Problém je, že ping je jiná služba, pokud je zkoumaný TCP server za firewallem a/nebo NATem, tak měříte něco jiného, a navíc je ping mnohdy blokován.
Takže jsem si udělal jednoduchý PowerShell skriptík na měření. Tu je.
function Test-Port ([string] $address, [int] $port, [ref] $outTime)
{
$status = $false
$tcpPortTimeout = 6500
$client = $null
$client = New-Object System.Net.Sockets.TcpClient
if ($client -ne $null) {
$waiter = $null
$startTime = [DateTime]::Now
$waiter = $client.BeginConnect($address, $port, $null, $null)
if ($waiter -ne $null) {
$finished = $waiter.AsyncWaitHandle.WaitOne($tcpPortTimeout, $false)
if ($finished -and $client.Connected) {
# when a local firewall blocks the outbount connection, the $finished is immediatelly $true
# but the $client.Connected is not connected ($client.Connected = $false)
$status = $true
} else {
# this means timeout or local firewall blocking
# just ignore any errors (such as when a local firewall blocks the outbount connection)
# why to wait for the EndConnect to succeed and sending FINs?
#$client.EndConnect($waiter) | Out-Null
}
$endTime = [DateTime]::Now
$client.Close()
}
}
$outTime.Value = ($endTime - $startTime).TotalMilliseconds
return $status
}
function Measure-Port ([string] $address, [int] $port)
{
[int] $outTime = 0
Test-Port $address $port ([ref] $outTime) | Out-Null
return $outTime
}
Jsou tam dvě funkce. Test-Port vrací $true, pokud bylo spojení úspěšně navázáno. Druhá funkce Measure-Port zjistí, kolik milisekund (ms) to trvalo. Maximální timeout si můžete nastavit nahoře pomocí proměnné $tcpPortTimeout. Aktuálně je to 6,5 sekundy.
A použití? Měřit potřebujete nejspíš maxima, minima a průměr za nějakou delší dobu:
(1..1000) | % { Measure-Port "sevecek.gopas.cz" 443 ([ref] $ms) } |
Measure-Object -Maximum -Minimum -Average
|