C# 网络流 getString 方法

标签 c# string sockets tcp eof

我正在编写一个库来简化我在未来项目中的网络编程。我希望它健壮且高效,因为这将在我 future 的几乎所有项目中出现。 (顺便说一句,服务器和客户端都将使用我的库,所以我没有在我的问题中假设一个协议(protocol))我正在编写一个函数来从网络流中接收字符串,我使用 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;
    }

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

最佳答案

Is this the best (efficient, practical, etc) to accomplish what I'm doing.

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

作为一个小推论,请注意在循环中附加到 string 绝不是一个好主意;如果您确实这样做了,请使用StringBuilder。但是不要那样做。我的代码更像是(嘿,你知道吗,这是我从 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

工作完成。

关于C# 网络流 getString 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11839778/

相关文章:

c# - LINQ:获取表列名称

java - 我无法解释 System.in.read() 行为

c - 翻译数组

Swift 枚举 : Getting enum value for string enum from int value

C++ 通过套接字发送文件和文本

sockets - 为什么 'netstat' 无法检测到某些打开的套接字?

java - 在linux中连接POP3S服务器

c# - 在sql server之间复制数据库

c# - 如何知道文件系统是否只读(.NET 标准)?

c# - 尝试配置 NServiceBus 以使用 NHibernate 持久性时出现异常