2016-05-16 4 views
1

StreamSocketを使用してソケットサーバーに接続しています。データを読み取るのに無限ループを使用しています。各データは「\ n \ n」で終わります。スニペットを以下に示します。しかし、ソケットがまだ生存しているかどうかはわかりません。サーバーが接続をシャットダウンするたびに、ReadAsync()は例外をスローします。接続が閉じられたときの通知方法UWPでStreamSocketを使用しているときにソケット接続がまだ生きているかどうかを確認するには?

public async Task<string> ReadData() { 
    StreamReader reader = new StreamReader(socket.InputStream.AsStreamForRead()); 
    char[] ch = new char[65536]; 
    int i = 0; 
    while (IsConnected) { 
     await reader.ReadAsync(ch, i++, 1); 
     if (i > 1 && ch[i - 1] == '\n' && ch[i - 2] == '\n') break; 
    } 
    return new StringBuilder().Append(ch, 0, i - 2).ToString(); 
} 

答えて

0

とサーバーが接続をシャットダウンするたびに、ReadAsync()が例外をスローします。

ungraceful disconnectが発生するため例外がスローされます。したがって、サーバ側で接続をシャットダウンする前に、ソケットにの保留中の読み取りまたは書き込み操作がない場合は、が存在することを確認してください。例外がないはずです。詳細は、StreamSocket classの備考部分を参照してください。接続が閉じられたときに通知する方法

グレースフルソケットクロージャは、長さ0リードとして相手側で検出できます。つまり、通常のストリーム終わりのように機能します。 Hereはあなたの参照のための同様のスレッドです。

ですから、接続があなたのシナリオに閉じているかどうかを確認するには、次のコードを使用することができます。

// break when the connection is closed 
if (ch[i - 1] == '\0') break; 

が続くのは、私が確認した全体の方法です:

public async Task<string> ReadData() 
{ 
    StreamReader reader = new StreamReader(socket.InputStream.AsStreamForRead()); 
    char[] ch = new char[65536]; 
    int i = 0; 
    while (true) 
    { 
     await reader.ReadAsync(ch, i++, 1); 
     // break when the connection is closed or data ends with '\n\n' 
     if (ch[i - 1] == '\0' || (i > 1 && ch[i - 1] == '\n' && ch[i - 2] == '\n')) break; 
    } 

    if (ch[i - 1] == '\0') 
    { 
     // do something here when the connection is closed 
    } 
    else 
    { 
     return new StringBuilder().Append(ch, 0, i - 2).ToString(); 
    } 
} 
0

毎回サーバーが接続をシャットダウンすると、ReadAsync()が例外をスローします。

これは、ほとんどのサーバーに対して予想されます。 TCP/IPは、接続を正常に終了するにはかなり高価な 4部分のハンドシェイクを持っていますが、サーバーの観点からは、それらのリソースを再利用するまで待つのは時間がかかります。したがって、多くのサーバーが接続をシャットダウンし、SocketError.ConnectionResetエラーが発生します。

私は自分のsocket error handlingブログ記事で説明しているように、その時点で適切な「正常終了」と考えられる通信状態であれば、同じ時点でConnectionResetの例外も受け入れるべきです。 (あなたのケースでは、メッセージが\n\nで完了した場合、適切な「閉じる」ポイントが表示されます)。接続が閉じられたときに通知する方法

? (それが突然閉じている場合)

あなたはConnectionReset例外を取得するか、または(それが正常に閉じている場合)あなたのReadAsync0を返します。ソケット接続がまだ生きているかどうかを知る方法

しかし...

書き込み、それにデータ:

ソケット接続がまだ生きているかどうかを検出するための唯一の信頼できる方法があります。私はブログ記事のhalf-open problemでこれを詳しく説明します。

ソケット通信のこの面白い特質のため、while (IsConnected)のようなコードは反パターンです。代わりに、がタイマに基づいて反対側にデータを送信する定期的なポーリングループを持つ必要があります。

P.S.可能であれば、rawソケットの代わりにSignalRを使用してください。彼らはあなたのためにすべてのハードものをやります。

関連する問題