C#

【C#】TcpClientのConnectのタイムアウト設定

どうも、〇NAKA(マルナカ)です。

これまでTCP通信のクライアント側の通信手順やC#でコードを記述する方法をまとめました。(以下のリンクカードから確認出来ます。)

【C#】TcpClientでクライアントの通信処理を作成TCP/IP通信は確実にデータの送受信ができるので通信品質が高く、現在でも使用されている通信手段の1つとして使用されています。 C...

実際にTCP通信を使うことになった際、クライアントはサーバーへリクエストを送信する為に頻繁に接続を要求することになります。サーバーが接続待ちの状態であれば通信を確立させることができますが、サーバーが接続待ち状態ではない場合だったらクライアントの接続は失敗してしまいます。

TcpClientのConnect(非同期ならConnectAsync)は約21秒経過してからタイムアウトします。下図のようにタイムアウトされるまでクライアントは長時間待たなければなりません。

TCPのタイムアウトは、サーバーから応答が返ってくるまで一定時間待ちます。1回目は3秒間待ちます。3秒間待って応答がなかったら、次は6秒間待ちます。6秒待って応答がなかったら、12秒間待ちます。2回リトライして接続できなかったらタイムアウトで例外を吐くという仕組みになっています。この待ち時間の合計が21秒(3秒+6秒+12秒)になるということです。(参考

この記事ではTcpClientの接続タイムアウトの時間を任意の値に設定する方法について紹介しています。是非参考にしてみてください。

TcpClientのタイムアウト処理

ここではいくつかの設定方法について紹介します。

①Task.Wait()を使用する

ConnectAsyncのタスクの実行が完了するまで指定されたミリ秒以内の間だけ待機する方法です。
try
{
    using (var tcpclient = new TcpClient())
    {
        //タイムアウトの時間を設定
        var timeout = 1000;
        var task = tcpclient.ConnectAsync(ipaddress, port);
        if (!task.Wait(timeout))  //ここで画面がフリーズしてしまう。
        {
            //タイムアウトの例外
            throw new SocketException(10060);
        }

        //接続後の処理を記述
    }
}
catch (Exception ex)
{
    Debug.WriteLine(ex.Message);
}

上記の例だと接続処理の実行を待機し、1秒間経過しても接続されなかったらタイムアウトの例外を吐きます。
しかしWaitを使ってしまうとデッドロックが発生するという欠点があります。1秒間待機中している間はUIが操作不可能になってしまいます。これだとあまりよくありませんよね。

②Task.WhenAny()を使用する

指定されたタスクのいずれかが完了してから次の処理に進むWhenAnyを使う方法です。
try
{
    using (var tcpclient = new TcpClient())
    {
        //タイムアウトの時間を設定
        var timeout = 1000;
        var task = tcpclient.ConnectAsync(ipaddress, port);
        if (await Task.WhenAny(task, Task.Delay(timeout)) != task)
        {
            //タイムアウトの例外
            throw new SocketException(10060);
        }

        //接続後の処理を記述 
    }
}
catch (Exception ex)
{
    Debug.WriteLine(ex.Message);
}

ConnectAsyncのタスクもしくは1秒間のタスクを同時に実行して、1秒間のタスクが先に完了したらタイムアウトの例外を吐きます。
この方法ならデッドロックは発生せずに、非同期で実行することが可能です。

まとめ

デフォルトのタイムアウトでは長時間の待機を強いられるので、タスクを待つ関数を上手いこと使ってタイムアウトの時間を短縮できるようにしましょう。

Task.WhenAny()を使うことでデッドロックが発生せず、待機することができますので是非活用してみてください。

以上、最後まで読んでいただきありがとうございました。

プログラミングを学習したいなら…

プログラミングスキルを身に付けるなら、プログラミングを効率良く学べる
プログラミングスクール」がオススメです。

特にこんな方にオススメ!!
これからエンジニアを目指したい
プログラミングの専門性を高めたい
プログラミングを学んで副業をしたい
エンジニアに転職して年収をアップさせたい

プログラミングを触ったことがない未経験からでも、プログラミングスクールで学習すれば、エンジニアへ就職・転職することも可能です。

あなたの「行動力」と「やる気」で、あなたの人生を大きく変えるチャンスになることでしょう。

プログラミングスクールに興味がある方は是非チェックしてみてください。

> プログラミングを学ぶ <

COMMENT

メールアドレスが公開されることはありません。

CAPTCHA