C#-将字符串写入流,长度为两个字节,而不是一个字节

本文关键字:字节 两个 一个 字符串 C#- | 更新日期: 2023-09-27 18:27:28

我正在创建一个易于使用的具有可扩展协议的服务器-客户端模型,其中服务器是Java,客户端可以是Java、C#等等。

我遇到了这个问题:Java数据流编写的字符串带有一个指定长度的short,后面跟着数据。

C#让我指定我想要的编码,但它只读取一个字节的长度。(实际上,它说"一次7位"……这很奇怪。这可能是我的问题的一部分?)

以下是我的设置:服务器在连接后会向客户端发送一个字符串。它是一个短字符串,所以第一个字节是0,第二个字节是9;该字符串有9个字节长。

//...
_socket.Connect(host, port);
var stream = new NetworkStream(_socket);
_in = new BinaryReader(stream, Encoding.UTF8);
Console.WriteLine(_in.ReadString()); //outputs nothing

在读取字符串之前读取单个字节当然会输出预期的字符串。但是,我如何设置流读取器以使用两个字节而不是一个字节作为长度来读取字符串?我需要子类化BinaryReader并重写ReadString()吗?

C#-将字符串写入流,长度为两个字节,而不是一个字节

如果我记得正确的话,C#BinaryWriter/Reader行为使用第8位来表示计数的最后一个字节在哪里。这允许最多127个计数放入一个字节,同时仍然允许实际计数值更大(即最多2^31-1);在这方面它有点像UTF8。

出于您自己的目的,请注意您正在编写整个协议(大概是),因此您可以完全控制两端。您在C#和Java中描述的两种行为都是由每种语言中本质上的helper类实现的。没有什么可以说你必须使用它们,这两种语言都提供了一种简单地将文本直接编码为字节数组的方法,你可以随心所欲地发送。

如果您确实想坚持使用基于Java的协议,那么可以使用BitConvertershortbyte[]之间进行转换,这样您就可以显式地发送和接收这两个字节。例如:

_in = new BinaryReader(stream, Encoding.UTF8);
byte[] header = _in.ReadBytes(2);
short count = BitConverter.ToInt16(header, 0);
byte[] data = _in.ReadBytes(count);
string text = Encoding.UTF8.GetString(data);
Console.WriteLine(text); // outputs something