public IPv4V6DualStackSpeculativeConnector(TcpConnectParam basicParam, TcpIpSystem system) : base(basicParam) { if (basicParam.DestHostname._IsEmpty()) { // IP address is specified AddAttempt(new Attempt(system, basicParam, 0)); return; } // Hostname is specified var hostInfo = system.GetHostInfo(true); if (hostInfo.IsIPv4Supported) { AddAttempt(new Attempt(system, new TcpConnectParam(basicParam.DestHostname, basicParam.DestPort, AddressFamily.InterNetwork, connectTimeout: basicParam.ConnectTimeout, dnsTimeout: basicParam.DnsTimeout), 0)); } if (hostInfo.IsIPv6Supported) { AddAttempt(new Attempt(system, new TcpConnectParam(basicParam.DestHostname, basicParam.DestPort, AddressFamily.InterNetworkV6, connectTimeout: basicParam.ConnectTimeout, dnsTimeout: basicParam.DnsTimeout), 0)); } }
// メインループ async Task MainLoopAsync(CancellationToken cancel) { while (cancel.IsCancellationRequested == false) { // インターネットが接続されるまで待機する if (await WaitForInternetAsync(cancel) == false) { // キャンセルされた return; } // 接続された _IsInternetConnected = true; FirstConnectedEvent.Set(true); EventListener.FireSoftly(this, NonsenseEventType.Nonsense, true); int lastNetworkVersion = TcpIp.GetHostInfo(false).InfoVersion; AsyncAutoResetEvent networkChangedEvent = new AsyncAutoResetEvent(); int eventRegisterId = TcpIp.RegisterHostInfoChangedEvent(networkChangedEvent); try { // 定期的に、現在もインターネットに接続されているかどうか確認する while (cancel.IsCancellationRequested == false) { // 一定時間待つ ただしネットワーク状態の変化が発生したときは待ちを解除する await TaskUtil.WaitObjectsAsync(cancels : cancel._SingleArray(), events : networkChangedEvent._SingleArray(), timeout : Options.CheckIntervalAfterEstablished); if (cancel.IsCancellationRequested) { break; } // 接続検査を再実行する // ただし、今度はタイムアウトを設定する CancellationTokenSource timeoutCts = new CancellationTokenSource(); timeoutCts.CancelAfter(Options.TimeoutToDetectDisconnected); bool ret = await StartEveryTestAsync(timeoutCts.Token, null); if (cancel.IsCancellationRequested) { break; } if (ret == false) { // 接続試験に失敗 (タイムアウト発生) // 切断された _IsInternetConnected = false; FirstDisconnectedEvent.Set(true); EventListener.FireSoftly(this, NonsenseEventType.Nonsense, false); break; } } } finally { TcpIp.UnregisterHostInfoChangedEvent(eventRegisterId); } } }