【问题标题】:NetworkStream.CanRead returns true but the buffer returns no valueNetworkStream.CanRead 返回 true 但缓冲区不返回值
【发布时间】:2010-12-17 07:25:52
【问题描述】:

我有一个 do while 循环,它从 NetworkStream 对象中读取缓冲区 while 条件是networkStream.CanRead,所以只要它可以读取,就应该继续从缓冲区读取。唯一的问题是当我从缓冲区读取并转换为字符串时,里面什么都没有。即它是空的。

为什么会这样?

这是一个 ASP.NET(VS2005) 应用程序

@dtb 代码信息:

我正在传递一个 NetworkStream 对象 networkStream

// between 2 functions in a loop
{
    SendMessage(networkStream, message);

    ReadMessage(networkStream);
}

有趣的是,如果它重新连接并再次连接,发送/读取工作正常。是否真的是 Send 的问题(我在这里没有例外)或重用 NetworkStream 对象。这在测试 TCP 服务器上本地运行良好,但是在生产中(Windows Server 2003)我遇到了上述问题(即无法从流中读取任何内容——直到我实际超时(退出循环)之后10 秒)

ReadMessage(networkStream)
{
    if (networkStream != null && networkStream.CanRead)
    {
        byte[] myReadBuffer = new byte[1024];
        StringBuilder myCompleteMessage = new StringBuilder();

        do
        {
            int numberOfBytesRead = networkStream.Read(myReadBuffer, 0, myReadBuffer.Length);
            string messageRead = Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead);
            myCompleteMessage.Append(messageRead);
        } while (networkStream.CanRead);
    }
}

【问题讨论】:

  • 请注意:它确实在第一次读取消息,在同一网络流上发送另一个数据请求之后,这发生在第二次发生
  • @soldieraman:如果 darkassassin93 的回答没有回答您的问题,请向我们展示您的代码。我感觉你在假设数据包边界和/或 Read 方法返回的字节数可能是错误的。
  • 那么让我们看看...流是一个字节序列,它没有消息的概念。因此,您需要将字节流分解为消息的东西。在您的案例中如何定义“消息”?能给我举个例子吗?您正在与哪个服务器通信?您不能使用CanRead 来检测两条消息之间的边界,并且您不应为此使用DataAvailable

标签: c# .net tcp ip networkstream


【解决方案1】:

CanRead 是一个静态值,指示流是否能够被读取。 DataAvailable 属性会让您知道数据是否可以读取。

【讨论】:

  • +1。这里的“静态值”表示该值由构造函数设置一次,并且在释放类之前永远不会更改(在这种情况下它将设置为false
  • 在关于 SO 的其他问题中,cmets 中有迹象表明可以更改 CanRead(我想也包括 CanWrite),并且在流关闭时发生。不过,你基本上是对的。
猜你喜欢
  • 2016-02-22
  • 2015-06-01
  • 2012-11-23
  • 1970-01-01
  • 1970-01-01
  • 2021-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多