【问题标题】:C# - Writing strings to a stream using two bytes for length, not oneC# - 使用两个字节作为长度而不是一个字节将字符串写入流
【发布时间】:2014-12-18 17:15:46
【问题描述】:

我正在创建一个易于使用的带有可扩展协议的服务器-客户端模型,其中服务器使用 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()?

【问题讨论】:

    标签: java c# string sockets utf-8


    【解决方案1】:

    如果我没记错的话,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
    

    【讨论】:

    • 是的,我可以完全控制协议。看看这个解决方法,似乎最简单的选择是为 C# 子类化 BinaryWriter/Reader 类。此外,无论如何我都需要反转字节顺序。谢谢你的时间,彼得!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-26
    • 2018-11-13
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多