使用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协议。 然后,我有一个等待数据在套接字中可用的循环(在一个线程中):
while (s_networkStream.DataAvailable)
{
    numberOfBytesRead = s_cometStream.Read(buffer, 0, buffer.Length);
    message.Append(Encoding.UTF8.GetString(buffer, 0, numberOfBytesRead));
    ExtractMessages(ref message);
}
这是我的两个问题: 文档说如果没有可用的数据,Read方法返回0。但在我的情况下,Read或者返回一个数字> 0(当读取了一些数据时)或者因为超时而引发异常......我在这里错过了什么? Read在哪种情况下返回0? 当我的连接使用HTTP协议时,此代码工作正常。我收到所有内容,如果消息大于我的缓冲区大小(CST_STREAM_BUFFER_SIZE),DataAvailable仍然为true,循环读取所有剩余数据。 但是,当我使用HTTPS尝试此操作时,它仅适用于小于我的缓冲区的消息。如果消息更大,则方法Read首先读取CST_STREAM_BUFFER_SIZE字节,然后DataAvailable变为false,尽管有些字节显然已准备好被读取。 在这种情况下,接收另一条消息“取消”剩余数据,因为DataAvailable再次变为true。 我究竟做错了什么?为什么DataAvailable在两种情况下都不一样? 任何帮助,将不胜感激。     
已邀请:
如果流关闭,它将仅返回0,因此将不再有数据。否则,如果可以读取数据则为正数,如果还没有数据可用则可能涉及阻塞。如果
CanTimeout
为真,则操作将在
ReadTimeout
过后抛出,没有可用数据。 听起来好像套接字已经打开和/或你试图读取太多你有一个协议在对话中发送多个数据块。 http://msdn.microsoft.com/en-us/library/system.io.stream.readtimeout.aspx     

要回复问题请先登录注册