2011-02-04 12 views
3

永続ソケットを持つアプリケーションがあります(アプリケーションの起動時および閉じたときに開いています)。SslStreamを使用しているときにNetworkStream.DataAvailableプロパティが正しい結果を返しません。

このソケットは、サーバーによってデータをプッシュするために使用されます。

この接続はHTTPまたはHTTPS可能性がありますので、私は私のオブジェクトを初期化するために、このコードを書いた:

s_tcpClient = new TcpClient(s_server.CometIp, s_server.CometPort); 
s_tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, false); 
s_tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, CST_STREAM_BUFFER_SIZE); 
s_tcpClient.ReceiveTimeout = 0; 

s_networkStream = s_tcpClient.GetStream(); 

s_cometStreamReader = null; 

if (s_server.Protocol == "HTTPS") 
{ 
    SslStream sslStream = new SslStream(
     s_tcpClient.GetStream(), 
     false, 
     new RemoteCertificateValidationCallback(ValidateServerCertificate) 
    ); 

    sslStream.AuthenticateAsClient(s_server.CometIp); 
    s_cometStreamReader = new StreamReader(sslStream, Encoding.UTF8, true, CST_STREAM_BUFFER_SIZE); 
    s_cometStream = sslStream as Stream; 
} 
else 
{ 
    s_cometStreamReader = new StreamReader(s_networkStream, Encoding.UTF8, true, CST_STREAM_BUFFER_SIZE); 
    s_cometStream = s_networkStream as Stream; 
} 

この道を、私はHTTPとHTTPSプロトコルの両方を扱うことができます。

  1. ドキュメント:ここ

    while (s_networkStream.DataAvailable) 
    { 
        numberOfBytesRead = s_cometStream.Read(buffer, 0, buffer.Length); 
        message.Append(Encoding.UTF8.GetString(buffer, 0, numberOfBytesRead)); 
        ExtractMessages(ref message); 
    } 
    

    は私の2つの質問です:

    その後、私はデータがソケットで利用可能になるのを待ち(スレッドで)このループを持っています利用可能なデータがない場合、Readメソッドは0を返します。しかし、私の場合、Readは数値> 0(一部のデータが読み込まれたとき)を返すか、タイムアウトしたために例外がスローされます...ここで何が欠けていますか?どのような状況の下でRead 0が返されますか?

  2. 私の接続がHTTPプロトコルを使用する場合、このコードは正常に動作します。私はすべてを受け取り、メッセージが自分のバッファサイズ(CST_STREAM_BUFFER_SIZE)より大きい場合、DataAvailableはtrueのままであり、ループは残りのすべてのデータを読み込みます。 しかし、これをHTTPSで試してみると、私のバッファよりも小さいメッセージに対してのみ動作します。メッセージが大きければ、最初にReadメソッドはCST_STREAM_BUFFER_SIZEバイトを読み取り、DataAvailableはfalseになりますが、いくつかのバイトは明らかに読み込み可能です。 この場合、DataAvailableが再びtrueになるため、別のメッセージを受信すると「残りのデータが取り除かれます」。 私は何が間違っていますか?どちらの場合でもDataAvailableが同じように機能しないのはなぜですか?

助けてください。

+0

私が間違っていることは誰も知りません、ここですか? – Rodolphe

+0

私の質問は答えるのが難しいのか、それともちょうど愚かなのですか? 私は本当にここで起こっていることを理解したいと思っています... – Rodolphe

答えて

2

ストリームがクローズされている場合は0だけが返され、それ以上のデータはになりません。それ以外の場合は、データを読み取ることができる場合は正の数で、データがまだ利用できない場合はブロックすることがあります。 CanTimeoutが真の場合、ReadTimeoutが経過した後に操作がスローされ、データが利用できません。

ソケットが開いたままになっている可能性があります。または、会話中に複数のチャンクを送信するプロトコルをあまりにも多く読み取っているようです。

http://msdn.microsoft.com/en-us/library/system.io.stream.readtimeout.aspx

+0

OK、ありがとう。これは私の最初の質問に答えます。私はあなたのprotobuf-netを昨日試したので、あなたが私に答えてくれるのは本当に奇妙な偶然です。 ; o) – Rodolphe

+0

@Rodolphe - どんな問題でも教えてください。 –

関連する問題