37190


C#でStreamReaderクラスのReadLine()を使ってTCP/IP通信を行っています。

[code]

    public NetworkStream netStream;
    public StreamWriter serverWriter = null;
    public StreamReader serverReader = null;
    
    netStream = server.GetStream();
    serverReader = new StreamReader(netStream, Encoding.UTF8);
    serverWriter = new StreamWriter(netStream, System.Text.Encoding.GetEncoding("shift_jis"));
    
    // スレッド内の処理
    lock (this) {
        while (true) {
            try {
                string message = reader.ReadLine();
    
                if (message != null) {
                    // 受信データの内容を解析
                    PerseData(message);
                }
                else {
                    result = false;
                    break;
                }
            }
            catch (Exception e) {
                if (IsKill) {
                    result = false;
                    break;
                }
            }
        }
    }
    
[/code]

このReadLine()はTimeout値を設定していませんので、データが来るか、それともクライアントからのDisconnectが来るまで終了しません。  
これだと、クライアントが異常終了してしまう、または通信ができない状態になると、ReadLine()から永久に抜けられなくなります。

そこで、クライアントからではなく、自身でReadLine()を抜ける正攻法というのをご存知の方おられますでしょうか？以前Timeout値を設定して行っていたのですが、Timeout値だと一度だけしかきかないので別の方法を探しております。


CC BY-SA 3.0
2017-08-14T06:15:31.657
37179
2017-08-15T10:10:41.147
24591
question
c#
c# で StreamReaderクラスのReadLine(). を使ったTCP/IP通信の強制終了のさせ方


タイムアウトを設定するのが正攻法です。

TCPソケット自体はタイムアウトが発生しても接続を再使用できる仕様となっておりますので、タイムアウトが発生した場合は`StreamReader.DiscardBufferData()`を呼んでから再通信を行えば規格レベルでは問題はないはずです。再通信が正常に動作すれば処理を続行すればよいですし、問題があるようなら再試行の時間を空けたり、`NetworkStream`自体を再度作成しなおすようにします。

一方スレッドやタスクなどを使用して例えば

[code]

    Task.WhenAny(streamReader.ReadLineAsync(), Task.Delay(timeout));
    
[/code]

のように他スレッドで時間を区切ることも可能ですが、`StreamReader`からアクセスされている`NetworkStream`をキャンセルするには接続自体を破棄するしかありません。ですので実現できる挙動はタイムアウト1回ごとに再接続を行うのと大差がなく、わざわざ実装する必要性はないです。


CC BY-SA 3.0
2017-08-14T12:10:36.933
37190
2017-08-14T12:10:36.933
5750
37179
answer


ストリームではなく非同期サーバーソケットを使えばクライアントから切断されたことも  
わかりますよ。  
<https://msdn.microsoft.com/ja-jp/library/fx6588te(v=vs.110).aspx>


CC BY-SA 3.0
2017-08-15T10:10:41.147
37222
2017-08-15T10:10:41.147
24490
37179
answer