// 1 個の Ping テストを実行する async Task <bool> PerformSinglePingTestAsync(InternetCheckerPingTestItem ping, CancellationToken cancel = default) { SendPingReply reply = await this.TcpIp.SendPingAsync(ping.IpAddress, pingTimeout : Options.PingTimeout, pingCancel : cancel, dnsCancel : cancel); return(reply.Ok); }
protected override async Task GetValueAsync(SortedDictionary <string, string> ret, RefInt nextPollingInterval, CancellationToken cancel = default) { SnmpWorkSettings settings = Host.Settings; if (settings.PingTargets._IsSamei("none") || settings.PingTargets._IsSamei("null")) { return; } string hopsStr = "Hops"; if (settings.HopsToTTL) { hopsStr = "TTL"; } string[] pingTargets = settings.PingTargets._Split(StringSplitOptions.RemoveEmptyEntries, ","); numPerform++; foreach (string pingTarget in pingTargets) { cancel.ThrowIfCancellationRequested(); ParseTargetString(pingTarget, out string hostname, out string alias); bool ok = false; try { IPAddress ipAddress = await LocalNet.GetIpAsync(hostname, cancel : cancel); if (FirstPing.IsFirstCall()) { // JIT 対策 try { await LocalNet.SendPingAsync(ipAddress, pingCancel : cancel); } catch { } } int numTry = 3; if (numPerform >= 2) { // SpeedTest が動作中の場合は SpeedTest が完了するまで待機する await TaskUtil.AwaitWithPollAsync(Timeout.Infinite, 10, () => !SpeedTestClient.IsInProgress, cancel); // 試行回数を指定する numTry = Math.Min(Math.Max(settings.PingNumTry, 1), 100); } SendPingReply reply = await LocalNet.SendPingAndGetBestResultAsync(ipAddress, pingCancel : cancel, numTry : numTry); if (reply.Ok) { double rtt = reply.RttDouble; rtt = Math.Min(rtt, 2.0); int ttl = reply.Ttl; bool ttl_ok = false; if (ttl == 0) { // Use ping command to get TTL try { var result = await EasyExec.ExecAsync(ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6?Consts.LinuxCommands.Ping6 : Consts.LinuxCommands.Ping, $"-W 1 -c 1 {ipAddress.ToString()}", cancel : cancel, throwOnErrorExitCode : false); string[] lines = result.OutputStr._GetLines(true); foreach (string line in lines) { OneLineParams param = new OneLineParams(line, ' ', false); string ttlStr = param._GetStrFirst("ttl"); if (ttlStr._IsFilled()) { ttl = ttlStr._ToInt(); ttl_ok = true; break; } } } catch (Exception ex) { ex._Debug(); } } else { ttl_ok = true; } ret.TryAdd($"Time - {alias}", (rtt * 1000.0).ToString("F3")); if (ttl > 128) { ttl -= 128; } else if (ttl > 64) { ttl -= 64; } int hops = 64 - ttl; if (ttl_ok == false) { hops = 0; } hops._SetMax(0); hops._SetMin(64); ret.TryAdd($"{hopsStr} - {alias}", hops.ToString()); ok = true; } } catch (Exception ex) { ex._Debug(); } if (ok == false) { ret.TryAdd($"Time - {alias}", ""); ret.TryAdd($"{hopsStr} - {alias}", "0"); } } }
// 実行スレッド void pingerThreadProc(object?param) { string optionsStr = this.DefaultOptions; // まずデフォルトのオプション文字列を読む string hostname = TargetHost; if (hostname._InStri("@")) { if (hostname._GetKeyAndValue(out string hostname2, out string tmp, "@")) { hostname = hostname2; // オプション文字列が個別に指定されていた場合は、それを先に付ける。同じ項目について上書きをすることになる、 optionsStr = tmp._NonNull() + "," + optionsStr; } } // オプション文字列のパース var options = QueryStringList.Parse(optionsStr, splitChar: ',', trimKeyAndValue: true); // IP アドレスバージョンの決定 AllowedIPVersions allowedIPVersions = AllowedIPVersions.All; string ipVerStr = options._GetStrFirst("ipver"); if (ipVerStr._InStr("4") && ipVerStr._InStr("6") == false) { allowedIPVersions = AllowedIPVersions.IPv4; } else if (ipVerStr._InStr("6") && ipVerStr._InStr("4") == false) { allowedIPVersions = AllowedIPVersions.IPv6; } bool preferV6 = false; string ipperfer = options._GetStrFirst("ipprefer"); if (ipperfer._InStri("6")) { preferV6 = true; } IPAddress GetIpAddress(string hostname, AllowedIPVersions allowedIPVersions) { var ip = hostname._ToIPAddress(allowedIPVersions, true); if (ip != null) { return(ip); } return(this.DnsClient.GetIpAddressAsync(hostname, allowedIPVersions, preferV6, noCache: true)._GetResult()); } if (TargetPort == 0) { // ping の実行 try { IPAddress ip = GetIpAddress(hostname, allowedIPVersions); SendPingReply ret = SendPing.Send(ip, null, Timeout); lock (lockObj) { ok = ret.Ok; finished = true; } } catch { lock (lockObj) { ok = false; finished = true; } } Console.Write(ok ? "+" : "-"); } else { int port = TargetPort; bool tcp_check = false; if (port >= 100000) { port -= 100000; tcp_check = true; } // TCP Connect の実行 try { if (tcp_check == false) { IPAddress ip = GetIpAddress(hostname, allowedIPVersions); Sock s = Sock.Connect(ip.ToString(), port, Timeout, true, true); try { if (TcpSendData) { s.SetTimeout(Timeout); long end_tick = Time.Tick64 + (long)Timeout; int num_packets = 0; while (true) { if (Time.Tick64 > end_tick) { break; } if (num_packets >= 16) { break; } byte[] data = new byte[1]; data[0] = (byte)'a'; if (s.SendAll(data) == false) { break; } ThreadObj.Sleep(1); num_packets++; } } s.Disconnect(); } catch { } } else { IPAddress ip = GetIpAddress(hostname, allowedIPVersions); if (tcp_check_do(ip.ToString(), port, Timeout) == false) { throw new ApplicationException(); } } lock (lockObj) { ok = true; finished = true; } } catch { lock (lockObj) { ok = false; finished = true; } } Console.Write(ok ? "*" : "-"); } //EndEvent.Set(); }