写入TcpClient和NetworkStream

时间:2012-07-13 21:55:21

标签: .net tcpclient

我对如何在.net中使用tcp流感到困惑。 现在,当我想写时,让我说40bytes我把它写入内存流然后调用ToArray()并将内存流写入networkstream + flush。

在服务器端,我使用Read(buf,0,len)并检查长度是否与我期望的完全一样。我是以愚蠢的方式做这件事的吗?我可以像我想要的那样写小字节,只要我准备阅读就冲洗吗?

当我阅读()时,我总能得到我期望的长度吗? (假设应用程序正确并且没有发生错误)它会阻塞直到我的大小准备好了吗?我不需要循环读取并构建我的缓冲区吗?让我说我期待像10k或更高的大尺寸然后我需要建立我的缓冲区吗?

3 个答案:

答案 0 :(得分:2)

我知道之前的两个答案都告诉你,但我会重复它们并添加一些东西:如果后续发送之间有足够的时间,它会像你期望的那样工作,这可能会让你相信它真的那样工作。但事实并非如此。

TCP很容易被视为一个水管,一端装满水。添加新的水不会告诉你任何有关它的尺寸,只需在管道中加入更多的水。

因此,您需要在流中实现自己的“消息”或“打包”。

然而,它并没有那么糟糕。流是鲁棒的,所以如果你的数据前缀是它的长度,你就可以让它工作 - 只需在接收端创建某种'数据包收集机制' - 有一些缓冲区可以保存部分数据包数据,直到你得到你需要的一切。

编辑:

回答你的问题:

  • Flush()与此无关。
  • 你不会得到你期望的尺寸。你将获得0到范围内的任何东西
  • 在你的尺码准备好之前它不会阻挡。它会尽可能多地获得你(0是可能) - 我认为这种行为可以改变,但它不会再有任何字节数Write() n在另一端
  • 您需要构建缓冲区
  • 并且是的,您确实需要手动构建缓冲区,方法是为数据添加长度

在这里,您对如何阅读缓冲区有一些想法:.NET blocking socket read until X bytes are available?

答案 1 :(得分:0)

Windows套接字没有内部同步机制。因此,您永远不会确定您获得的字节部分是最终的,并且不需要其他数据。您始终需要跟踪所有检索到的数据并确定何时可以停止检索。

答案 2 :(得分:0)

如果流耗尽,或者至少达到缓冲区大小的1,则读取大小为0。它可以是该范围内的任何尺寸。常见大小是网络MTU的倍数(约1452字节)。

您需要自己实现逻辑以逐渐填充缓冲区,直至达到所需的大小。

发送的块大小与收到的块大小之间没有任何关联。

文件系统基本上是唯一的常见Stream实现,它总是完全填满请求的缓冲区,除了在文件的末尾。其他Stream实现不能保证。

所有这些都是为了表现而做出的设计选择。