2009-09-08 7 views
3

EndRead呼び出しで0バイトを受け取っているC#のAsync Socketsで、サーバーが実際に私たちを切断してしまったのでしょうか?Socket.EndRead 0バイトは切断されたことを意味しますか?

多くの例では、このようなケースが考えられますが、予想外に頻繁に切断されています。

このコードは正しいですか?または、endResult < = 0は実際に接続状態について何も意味しませんか?

private void socket_EndRead(IAsyncResult asyncResult) 
{ 
    //Get the socket from the result state 
    Socket socket = asyncResult.AsyncState as Socket; 

    //End the read 
    int endResult = Socket.EndRead(asyncResult); 

    if (endResult > 0) 
    { 
    //Do something with the data here 


    } 
    else 
    { 
    //Server closed connection? 
    } 
} 
+0

私は実際にはSslStreamを使用していることを共有することを無視してはいけないと思うが、私は基本ストリームがソケットに沸騰することは確かだ。 しかし、SslStreamを使用しているため、ソケットの接続状態を確認するアクセス権がありません。おそらく私はEndReadから0バイトを受け取るたびにSslStream.CanReadをチェックしなければならないでしょうか? – Redth

答えて

1

0読み取りの長さは、グレースフルシャットダウンを意味します。切断はerror(10054,10053または10051)をスローします。

実際には、接続が有効であっても0の長さの読み取りが完了していますが、扱う唯一の方法は0の長さの読み取りでソケットの状態を確認することです。状況は次のとおりです。受信用ソケットに複数のバッファをポストします。投稿されたスレッドは、プールによってトリムされます。 OSは、要求を行ったスレッドがなくなったことに気付き、文書化されているようにエラー995 ERROR_OPERATION_ABORTEDで通知された操作を通知します。しかし、私が見つけたのは、複数の操作(つまり、複数の読み取り)が投稿された場​​合、の最初のにエラー995が通知され、それ以降は成功と長さ0で通知されます。

+0

私は私の質問にコメントを追加しました...だから、0長さを得るたびにSslStream.CanReadを使用しますEnd Read十分にあると思いますか? – Redth

+0

ネットワークストリームの* top *に暗号化されたストリームがある場合は、非常に異なると考えます。まず、SslStreamは複数の投稿を受け入れることができないため、私が記述している状況には対応できません。第2に、ソケットが0でエラーを返して成功した場合でも、SslStreamはこれを既に見ていて動作しています(つまり、あなたのSsl状態では続行できるようになります)。再度接続してください。 –

+0

typos galore:thinks =>物事、今できるようになります=> will * not * –

5

From the docs:リモートホストがソケット接続をシャットダウンし、すべての利用可能なデータを受信した場合

、EndReadメソッドは直ちに終了し、ゼロバイトを返します。

したがって、0バイトはリモートクローズを示します。

+0

さて、MSDNの言葉で言えば、0バイトが受信された場合、接続が閉じられなければならず、接続が閉じられた場合に0バイトが受信されることを明示的に暗示しません。たぶん私はこの声明の論理にあまりにも遠すぎて読んでいる... – Redth

+1

それはブロックされた読み取りです。これは、1つ以上のバイトが入るまで*永遠に待機することを意味します。ゼロバイトが表示された場合、唯一の可能性はリモートホストがソケットを閉じたことだけです。 –

+0

0バイトを読み込む要求を読み始めるとどうなりますか?私は0バイトを読むことを要求する場合、接続をチェックする方法が閉じられていますか? – Benny

関連する問題