C# Network Stream getString method

本文关键字:method getString Stream Network | 更新日期: 2024-11-08 22:37:48

我正在编写一个库来简化未来项目中的网络编程。我希望它健壮而高效,因为这将用于我未来几乎所有的项目。(顺便说一句,服务器和客户端都将使用我的库,所以我在我的问题中没有假设协议)我正在编写一个用于从网络流接收字符串的函数,其中我使用 31 字节的缓冲区和一个用于哨兵的缓冲区。哨兵值将指示哪个字节(如果有)是 EOF。这是我的代码供您使用或审查...

public string getString()
    {
        string returnme = "";
        while (true)
        {
            int[] buff = new int[32];
            for (int i = 0; i < 32; i++)
            {
                buff[i] = ns.ReadByte();
            }
            if (buff[31] > 31) { /*throw some error*/}
            for (int i = 0; i < buff[31]; i++)
            {
                returnme += (char)buff[i];
            }
            if (buff[31] != 31)
            {
                break;
            }
        }
        return returnme;
    }

编辑:这是完成我正在做的事情的最佳(高效,实用等)吗?

C# Network Stream getString method

这是完成我正在做的事情的最佳(高效、实用等)吗?

不。首先,您将自己限制为 0-255 代码点范围内的字符,这还不够,其次:序列化字符串是一个已解决的问题。只需使用Encoding,通常是UTF-8。作为网络流的一部分,这可能意味着"编码长度,编码数据"和"读取长度,缓冲大量数据,解码数据"。另请注意:如果 EOF 返回负值,则ReadByte()无法正确处理 EOF 方案。

作为一个小推论,请注意,在循环中追加到string从来都不是一个好主意;如果你这样做了,请使用StringBuilder。但不要那样做。我的代码会更像(嘿,whadya知道,这是我从protobuf-net中读取的实际字符串代码,简化了一点):

// read the length         
int bytes = (int)ReadUInt32Variant(false);
if (bytes == 0) return "";
// buffer that much data
if (available < bytes) Ensure(bytes, true);
// read the string
string s = encoding.GetString(ioBuffer, ioIndex, bytes);
// update the internal buffer data
available -= bytes;
position += bytes;
ioIndex += bytes;
return s;

最后,我想说:如果您要发送结构化消息,请认真考虑使用专门处理此内容的预卷序列化 API。例如,您可以执行以下操作:

var msg = new MyMessage { Name = "abc", Value = 123, IsMagic = true };
Serializer.SerializeWithLengthPrefix(networkStream, msg);

在另一端:

var msg = Serializer.DeserializeWithLengthPrefix<MyMessage>(networkStream);
Console.WriteLine(msg.Name); // etc

工作完成。

我认为tou应该使用具有固定大小的StringBuilder对象以获得更好的性能。