我正在创建一个易于使用的服务器 - 客户端模型,该模型具有可扩展协议,其中服务器使用Java,客户端可以是Java,C#,还有什么。
我遇到了这个问题:Java数据流写入字符串with a short designating the length,然后是数据。
C#允许我指定我想要的编码but it only reads one byte for the length。 (实际上,它一次说'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()?
答案 0 :(得分:1)
如果我没记错的话,C#BinaryWriter / Reader行为使用第8位来表示计数的最后一个字节的位置。这允许最多127个计数适合单个字节,同时仍允许实际计数值大得多(即最多2 ^ 31-1);在这方面,它有点像UTF8。
出于您自己的目的,请注意您正在编写整个协议(大概),因此您可以完全控制两端。您在C#和Java中描述的这两种行为都是由每种语言中基本上 helper 的类实现的。没有什么可以说你必须使用它们,并且这两种语言提供了一种简单地将文本直接编码为字节数组的方法,你可以随意发送它们。
如果您确实希望坚持使用基于Java的协议,可以使用BitConverter
在short
到byte[]
之间进行转换,以便发送和接收这两个字节明确。例如:
_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