在块中写入并在流对象c#中接收块

Moo*_*ons 1 c# stream

我有两个应用程序在服务器上,一个在客户端上.

在服务器端,我写这样的流.

NetworkStream stream = client.GetStream();

byte[] msg = System.Text.Encoding.ASCII.GetBytes(messageSent);

stream.Write(msg, 0, msg.Length);
stream.Write(msg, 0, msg.Length);
Run Code Online (Sandbox Code Playgroud)

我在逐个流中写了多个字符串.弦的长度是可变的,达到最大长度约为500

问题:

如何在块中以客户端方式阅读

发生的事情有时候我会得到组合字符串

就像我送A,B,C一样

在客户端我收到了A,BC

我是这样的客户:

bytes = stream.Read(data, 0, data.Length);
Run Code Online (Sandbox Code Playgroud)

任何帮助表示赞赏.

Jon*_*eet 5

是的,你有一个 - 只是一个字节序列 - 但你把它视为不是一个流; 好像它是一个面向消息的协议.

从根本上说,通过简单的基于流的通信,没有任何内在的东西可以将流分解为消息.如果你想这样做,你需要在顶部构建一个层.有三种常见的方法:

  • 使用您在阅读时发现的"消息结束"标记
  • 在每条消息之前使用长度前缀
  • 使用一种混合,其中每个消息可以由多个块组成,每个块都是长度前缀的,0长度的块表示"消息结束"

其中第二个可能是最简单的,但有一个限制,你需要知道消息在开始发送之前有多大.第三个选项通过具有可变数量的块来绕过它.如果可能的话,我个人会避免使用第一个选项 - 除非你有一些自然的"消息结束"令牌,你永远不想将其作为数据包含在消息中,你必须开始计算逃避计划,这很痛苦...而且也很难读取数据.

当然,你不必从头开始做所有这些.如果你有两端的.NET,你可以使用BinaryReaderBinaryWriter支持长度前缀的字符串,并且还有很多序列化框架,通常以某种形式或其他形式处理它.(我个人的偏好是Protocol Buffers,因为它是高效的,独立于平台的,以及我在工作中使用的东西.有两个常见的.NET端口 - 一个是我自己,另一个是Marc Gravell.)