C# socket动态缓存

jiaoshiyao 2017-11-20 03:06:22
每个tcp消息定义可能大到30M,也可能小到50字节
就像http请求一样,post可以达到30M
按照现在的写法来
byte[] buffer = new byte[缓冲区大小];
如果我设置缓冲区大小为10K,那么30M的如何接受,如果设置缓冲区大小为30M,那么几个链接服务器就垮了
到底这个缓冲区怎么设置
...全文
617 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_40295757 2017-11-28
  • 打赏
  • 举报
回复
Mark~~
  • 打赏
  • 举报
回复
引用 14 楼 chenandczh 的回复:
自己写个数据协议,把大数据按分包的形式切割并分发,接收端缓存数据并合并,如果有并发,控制好就可以了。
其实并发大可以不控制,每次收到一个包就看一下没有收完的包里面有能不能凑齐全部的包,能凑齐就凑齐完整数据抛出去处理,不能就丢在未收完缓冲区里面。
绿领巾童鞋 2017-11-22
  • 打赏
  • 举报
回复
自己写个数据协议,把大数据按分包的形式切割并分发,接收端缓存数据并合并,如果有并发,控制好就可以了。
lescper2011 2017-11-21
  • 打赏
  • 举报
回复
缓存一般设置为1024,循环读取直至结束
jiaoshiyao 2017-11-21
  • 打赏
  • 举报
回复
引用 10 楼 sp1234 的回复:
List<Byte> 本身就是动态高速处理数据的,比如说原本有1998个字节,而你再向其插入3个字节,而 List<Byte>可能申请了2000个字节的缓存空间,而 List<Byte> 对外还是只是对外显示自己只有 2001个字节的大小,当再增加少量字节时根本不会去拷贝缓存结构。这种智能管理的设计不比手写一个简单的 byte[ ] 数组反复拷贝高明多了吗?
用list<byte>有很多问题,例如很多代码都是基于byte[]实现的,例如Encoding.Utf8.GetString,还有如果list<byte>是基于内存片段拼接出来的,那么下标操作会不会影响很多效率(array[i]可以直接寻址,list<byte>如果2001个byte,那么他可能3个1000字节的array拼接起来的,那么如果我对list[1001]进行下标操作,他可能要1001/1000,取出来array拼接的对象,再array[1001%1000]操作),最重要的就是如果用list<byte>定义了,那么如何调用Encoding.Utf8.GetString就要Encoding.Utf8.GetString(List.ToArray())
  • 打赏
  • 举报
回复
List<Byte> 本身就是动态高速处理数据的,比如说原本有1998个字节,而你再向其插入3个字节,而 List<Byte>可能申请了2000个字节的缓存空间,而 List<Byte> 对外还是只是对外显示自己只有 2001个字节的大小,当再增加少量字节时根本不会去拷贝缓存结构。这种智能管理的设计不比手写一个简单的 byte[ ] 数组反复拷贝高明多了吗?
  • 打赏
  • 举报
回复
引用 6 楼 jiaoshiyao 的回复:
[quote=引用 2 楼 ourhouzi 的回复:] 你不需要修改socket的缓存 你需要的是自己写个缓存List<byte>来获取socket接受到的数据 然后递归判断list长度是否大于数据长度,是的话就把前面一段数据长度截取出来就是条完整的数据,剩下的数据继续判断直到list长度小于数据长度;然后再接受数据。
用了list还不如动态创建byte[],list太耗时了[/quote] 单纯纠结技术名词儿无用,还是先要理解技术背后的设计知识。
  • 打赏
  • 举报
回复
你就算是设置程序接收缓冲区是 1 个字节,也照样可以接收30M字节的一个发送(一次xxxx.send(data)命令发送出来的内容)。正常的通讯程序是否成功,跟什么缓冲区根本没有关系。
ourhouzi 2017-11-21
  • 打赏
  • 举报
回复
引用 6 楼 jiaoshiyao 的回复:
[quote=引用 2 楼 ourhouzi 的回复:] 你不需要修改socket的缓存 你需要的是自己写个缓存List<byte>来获取socket接受到的数据 然后递归判断list长度是否大于数据长度,是的话就把前面一段数据长度截取出来就是条完整的数据,剩下的数据继续判断直到list长度小于数据长度;然后再接受数据。
用了list还不如动态创建byte[],list太耗时了[/quote]
引用 6 楼 jiaoshiyao 的回复:
[quote=引用 2 楼 ourhouzi 的回复:] 你不需要修改socket的缓存 你需要的是自己写个缓存List<byte>来获取socket接受到的数据 然后递归判断list长度是否大于数据长度,是的话就把前面一段数据长度截取出来就是条完整的数据,剩下的数据继续判断直到list长度小于数据长度;然后再接受数据。
用了list还不如动态创建byte[],list太耗时了[/quote] 你没明白我的意思
ourhouzi 2017-11-21
  • 打赏
  • 举报
回复
引用 11 楼 jiaoshiyao 的回复:
[quote=引用 10 楼 sp1234 的回复:] List<Byte> 本身就是动态高速处理数据的,比如说原本有1998个字节,而你再向其插入3个字节,而 List<Byte>可能申请了2000个字节的缓存空间,而 List<Byte> 对外还是只是对外显示自己只有 2001个字节的大小,当再增加少量字节时根本不会去拷贝缓存结构。这种智能管理的设计不比手写一个简单的 byte[ ] 数组反复拷贝高明多了吗?
用list<byte>有很多问题,例如很多代码都是基于byte[]实现的,例如Encoding.Utf8.GetString,还有如果list<byte>是基于内存片段拼接出来的,那么下标操作会不会影响很多效率(array[i]可以直接寻址,list<byte>如果2001个byte,那么他可能3个1000字节的array拼接起来的,那么如果我对list[1001]进行下标操作,他可能要1001/1000,取出来array拼接的对象,再array[1001%1000]操作),最重要的就是如果用list<byte>定义了,那么如何调用Encoding.Utf8.GetString就要Encoding.Utf8.GetString(List.ToArray())[/quote] List<Byte> 只是一个自定义缓存,是存放socket接受的数据的;你需要做的是查看List<Byte>里面是否有一条以上的数据 检查规则上面已经说了,如果有就把里面的一条完整数据截取出来。至于你后面要怎么处理,是转 string 还是 图像 还是一个自定义对象都 是看你的协议的。
jiaoshiyao 2017-11-20
  • 打赏
  • 举报
回复
引用 2 楼 ourhouzi 的回复:
你不需要修改socket的缓存 你需要的是自己写个缓存List<byte>来获取socket接受到的数据 然后递归判断list长度是否大于数据长度,是的话就把前面一段数据长度截取出来就是条完整的数据,剩下的数据继续判断直到list长度小于数据长度;然后再接受数据。
用了list还不如动态创建byte[],list太耗时了
jiaoshiyao 2017-11-20
  • 打赏
  • 举报
回复
引用 4 楼 From_TaiWan 的回复:
可以考虑Array.Resize 第二个问题 你可以定义一个结构 struct receivedData { uint dataLength; datatype dataContent; } List<receivedData> recData=new …… 读取数据存入recData,然后可以分别操作
Array.ReSize不行,这是resize的源码,就是重新创建一个数组啊
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        public static void Resize<T>(ref T[] array, int newSize) {
            if (newSize < 0)
                throw new ArgumentOutOfRangeException("newSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            Contract.Ensures(Contract.ValueAtReturn(out array) != null);
            Contract.Ensures(Contract.ValueAtReturn(out array).Length == newSize);
            Contract.EndContractBlock();
 
            T[] larray = array;                
            if (larray == null) {
                array = new T[newSize];
                return;
            }
        
            if (larray.Length != newSize) {
                T[] newArray = new T[newSize];
                Array.Copy(larray, 0, newArray, 0,  larray.Length > newSize? newSize : larray.Length);
                array = newArray;
            }
        }
秋的红果实 2017-11-20
  • 打赏
  • 举报
回复
可以考虑Array.Resize 第二个问题 你可以定义一个结构 struct receivedData { uint dataLength; datatype dataContent; } List<receivedData> recData=new …… 读取数据存入recData,然后可以分别操作
xian_wwq 2017-11-20
  • 打赏
  • 举报
回复
引用 1 楼 jiaoshiyao 的回复:
还有一个问题是,我的tcp消息的数据包格式是前面4个是长度,后面紧跟着所有的数据, 我想说,如果我分开接受tcp可以不 就是接受2次,第一次就只接受4个字节的长度,第2次接受后面的所有数据,不知道效率会不会大幅度降低
报头加数据的设计是因为tcp是基于流的, 接收的数据长度可能够,也可能不够,是没有办法控制的, 但可以从接收buffer中先只解析报头,然后再处理后续数据, 对buffer的操作都在内存中进行, 相对于socket通讯的开销,分包处理对整体效率的影响可以忽略
ourhouzi 2017-11-20
  • 打赏
  • 举报
回复
你不需要修改socket的缓存 你需要的是自己写个缓存List<byte>来获取socket接受到的数据 然后递归判断list长度是否大于数据长度,是的话就把前面一段数据长度截取出来就是条完整的数据,剩下的数据继续判断直到list长度小于数据长度;然后再接受数据。
jiaoshiyao 2017-11-20
  • 打赏
  • 举报
回复
还有一个问题是,我的tcp消息的数据包格式是前面4个是长度,后面紧跟着所有的数据, 我想说,如果我分开接受tcp可以不 就是接受2次,第一次就只接受4个字节的长度,第2次接受后面的所有数据,不知道效率会不会大幅度降低

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧