我正在编写一个库,以便在将来的项目中简化我的网络编程。我希望它强大而有效,因为这将在我将来的几乎所有项目中都有。 (顺便说一下,服务器和客户端都将使用我的库,所以我不会在我的问题中假设一个协议)我正在编写一个函数来接收来自网络流的字符串,其中我使用31个字节的缓冲区和一个用于sentinel。 sentinel值将指示哪个字节(如果有的话)是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 :(得分:3)
这是最好的(高效,实用等)来完成我正在做的事情。
没有。首先,您将自己限制在0-255代码点范围内的字符,并且不够,其次:序列化字符串是一个已解决的问题。只需使用Encoding
,通常为UTF-8。作为网络流的一部分,这可能意味着“编码长度,编码数据”和“读取长度,缓冲那么多数据,解码数据”。另请注意:如果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
完成工作。
答案 1 :(得分:0)
我认为您应该使用固定大小的StringBuilder对象以获得更好的性能。