C# 使用SslStream时,NetworkStream.DataAvailable属性未返回正确的结果

C# 使用SslStream时,NetworkStream.DataAvailable属性未返回正确的结果,c#,.net,sslstream,C#,.net,Sslstream,我有一个带有持久套接字的应用程序(当应用程序启动时它是打开的,并随应用程序一起关闭) 服务器使用此套接字推送某些数据 由于此连接可以是HTTP或HTTPS,因此我编写了以下代码来初始化我的对象: s_tcpClient = new TcpClient(s_server.CometIp, s_server.CometPort); s_tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAli

我有一个带有持久套接字的应用程序(当应用程序启动时它是打开的,并随应用程序一起关闭)

服务器使用此套接字推送某些数据

由于此连接可以是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的数字(当一些数据被读取时),要么抛出一个异常,因为它超时了。。。我错过了什么,在这里?在什么情况下读取返回0

  • 当我的连接使用HTTP协议时,此代码工作正常。我接收所有信息,如果消息大于我的缓冲区大小(CST_STREAM_buffer_size),DataAvailable保持为true,循环读取所有剩余数据。 但当我尝试使用HTTPS时,它只适用于小于缓冲区的消息。如果消息更大,则Read方法首先读取CST_STREAM_BUFFER_SIZE字节,然后DataAvailable变为false,尽管某些字节显然已准备好读取。 在这种情况下,由于DataAvailable再次变为true,因此接收到另一条消息“unstack”剩余的数据。 我做错了什么?为什么DataAvailable在这两种情况下的行为不一样


  • 任何帮助都将不胜感激。

    如果流关闭,它将只返回0,因此不再有数据出现。否则,如果可以读取数据,则为正数,如果没有可用数据,则可能会导致阻塞。如果
    CanTimeout
    为true,则在
    ReadTimeout
    没有可用数据的情况下通过后,操作将抛出

    听起来可能是套接字一直处于打开状态,或者您试图读取太多的内容,因为您有一个在对话中发送多个数据块的协议


    好的,谢谢。这回答了我的第一个问题。我昨天试过你的protobuf网络,你就是那个回答我的人,这真是一个奇怪的巧合;o) @Rodolphe-有什么问题,让我知道。没人知道我做错了什么,在这里?我的问题有那么难回答还是很愚蠢?我真的很想知道这里发生了什么。。。