我正在为服务器编写客户端,该服务器通常以500或更少字节的形式将数据作为字符串发送。但是,数据有时会超过该数据,并且一组数据可能包含200,000个字节,因为所有客户端都知道(在初始化或重要事件时)。但是,我不希望每个客户端都运行50 MB的套接字缓冲区(如果可能的话)。
每组数据由空\0
字符分隔。我应该在什么样的结构中存储部分发送的数据集?
例如,服务器可能会发送ABCDEFGHIJKLMNOPQRSTUV\0WXYZ\0123!\0
。我希望独立处理ABCDEFGHIJKLMNOPQRSTUV
,WXYZ
和123!
。此外,服务器可以发送ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890LOL123HAHATHISISREALLYLONG
而不使用终止字符。我希望将数据集存储在某处以便以后添加和处理。
此外,如果重要的话,我正在使用异步套接字方法(BeginSend
,EndSend
,BeginReceive
,EndReceive
)。
目前我在List<Byte>
和StringBuilder
之间进行辩论。对这种情况进行任何比较都会非常有帮助。
答案 0 :(得分:4)
将套接字中的数据读入缓冲区。当您获得终止字符时,将其转换为消息并将其发送到其余代码。
另外,请记住TCP是流,而不是数据包。因此,您永远不应该假设您将在一次阅读中一次性发送所有内容。
就缓冲区而言,每个连接最多只需要一个缓冲区。我可能从合理地期望接收的最大尺寸开始,如果填充,则创建一个更大尺寸的新缓冲区 - 典型的策略是当你用完时增加一倍的大小避免通过太多的分配来搅拌。
如果你有多个传入连接,你可能想要做一些事情,比如创建一个缓冲池,并在完成它们时将它们返回池中。
答案 1 :(得分:2)
您可以使用List<byte>
作为缓冲区,因此.NET框架会根据需要自动扩展它。当您找到空终止符时,可以使用List.RemoveRange()
从缓冲区中删除该消息并将其传递给下一层。
你可能想要添加一个检查并在超过一定长度时抛出异常,而不是等到客户端内存不足。
(这与Ben S的答案非常相似,但我认为在面对编码问题时,字节数组比StringBuilder更强大。将字节解码为字符串最好在更高的位置完成,一旦完成消息)。
答案 2 :(得分:1)
我只使用StringBuilder
并一次读取一个字符,每当我点击一个空终止符时复制并清空构建器。
答案 3 :(得分:0)
我写了关于Java套接字的答案,但概念是一样的。
What's the best way to monitor a socket for new data and then process that data?