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;
}
编辑:这是完成我正在做的事情的最佳(高效,实用等)吗?
这是完成我正在做的事情的最佳(高效、实用等)吗?
不。首先,您将自己限制为 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对象以获得更好的性能。