我对如何在.net中使用tcp流感到困惑。 现在,当我想写时,让我说40bytes我把它写入内存流然后调用ToArray()并将内存流写入networkstream + flush。
在服务器端,我使用Read(buf,0,len)并检查长度是否与我期望的完全一样。我是以愚蠢的方式做这件事的吗?我可以像我想要的那样写小字节,只要我准备阅读就冲洗吗?
当我阅读()时,我总能得到我期望的长度吗? (假设应用程序正确并且没有发生错误)它会阻塞直到我的大小准备好了吗?我不需要循环读取并构建我的缓冲区吗?让我说我期待像10k或更高的大尺寸然后我需要建立我的缓冲区吗?
答案 0 :(得分:2)
我知道之前的两个答案都告诉你,但我会重复它们并添加一些东西:如果后续发送之间有足够的时间,它会像你期望的那样工作,这可能会让你相信它真的那样工作。但事实并非如此。
TCP很容易被视为一个水管,一端装满水。添加新的水不会告诉你任何有关它的尺寸,只需在管道中加入更多的水。
因此,您需要在流中实现自己的“消息”或“打包”。
然而,它并没有那么糟糕。流是鲁棒的,所以如果你的数据前缀是它的长度,你就可以让它工作 - 只需在接收端创建某种'数据包收集机制' - 有一些缓冲区可以保存部分数据包数据,直到你得到你需要的一切。
编辑:
回答你的问题:
Flush()
与此无关。Write()
n在另一端在这里,您对如何阅读缓冲区有一些想法:.NET blocking socket read until X bytes are available?
答案 1 :(得分:0)
Windows套接字没有内部同步机制。因此,您永远不会确定您获得的字节部分是最终的,并且不需要其他数据。您始终需要跟踪所有检索到的数据并确定何时可以停止检索。
答案 2 :(得分:0)
如果流耗尽,或者至少达到缓冲区大小的1,则读取大小为0。它可以是该范围内的任何尺寸。常见大小是网络MTU的倍数(约1452字节)。
您需要自己实现逻辑以逐渐填充缓冲区,直至达到所需的大小。
发送的块大小与收到的块大小之间没有任何关联。
文件系统基本上是唯一的常见Stream实现,它总是完全填满请求的缓冲区,除了在文件的末尾。其他Stream实现不能保证。
所有这些都是为了表现而做出的设计选择。