C#Network Stream getString方法

时间:2012-08-07 05:30:32

标签: c# string sockets tcp eof

我正在编写一个库,以便在将来的项目中简化我的网络编程。我希望它强大而有效,因为这将在我将来的几乎所有项目中都有。 (顺便说一下,服务器和客户端都将使用我的库,所以我不会在我的问题中假设一个协议)我正在编写一个函数来接收来自网络流的字符串,其中我使用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;
    }

编辑:这是最好的(高效,实用等)来完成我正在做的事情。

2 个答案:

答案 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对象以获得更好的性能。