之前困恼了很久的问题,终于解决了,项目要求使用Upd传输,128000的采样率 ,每次一个通道2000个数据,一个数据用3个字节传输,共8通道,最后两字节验证码,最后计算转成double值,用曲线显示并保存文件。
则:
128000/2000=62(次)
1/62≈0.016(s)=16(ms)
200038+2=48002(字节)
相当于循环16ms传输48002个字节。

在之前的项目中,没有解决,让c++的同事写的插件,空闲时还是要自己研究下哈,但是资料真的好难找,最后自己摸索,实现了,下面把帮助类贴上,供大家一起讨论学习。

public  class BigDataUDPServerHelper
{private Socket _server;private IPAddress Ip;//本机设备ippublic int Port;//本机设备端口号private EndPoint _remote;//对方设备Ip及端口public int PagLength = 1472;//从服务读取的数据量,因为BeginReceiveFrom每次都是提前设置下一次接受,要注意如何传递int buffIndex = 0;//使用的缓存数组索引public byte[][] recvBuff0;//缓存数组readonly int MAX_BUFFLEN = 32;//最大缓存数组private int _readLen = 6002; //从服务读取的数据量,因为BeginReceiveFrom每次都是提前设置下一次接受,要注意如何传递public BigDataUDPServerHelper(string clientIpString,int clientPort,int size){if (!IPAddress.TryParse(GetLocalIP(), out Ip)){MessageBox.Show("获取本机信息错误!");return ;}if (!int.TryParse(GetLocalValidPort(), out Port)){MessageBox.Show("本机没有可用的端口!");return ;}var clientIp= IPAddress.Parse(clientIpString);_remote = new IPEndPoint(clientIp, clientPort);PagLength = size;Init();}/// <summary>/// 缓存清零,初始化/// </summary>public void BuffInit(){recvBuff0 = new byte[MAX_BUFFLEN][];for (int i = 0; i < MAX_BUFFLEN; i++){recvBuff0[i] = new byte[50000];}}/// <summary>/// 初始化服务/// </summary>public void Init(){BuffInit();_server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);_server.Bind(new IPEndPoint(Ip, Port));//绑定端口号和IP//接受回调 ReceiveMsg是回调函数_server.BeginReceiveFrom(recvBuff0[buffIndex], 0, PagLength, 0, ref _remote, ReceiveMsg, null);}#region 接收/// <summary>/// 设置接收长度/// </summary>/// <param name="size"></param>public void SetBufferSize(int size){PagLength = size;}public int realBytesRecv = 0;//实际已接收字节数public event Action<byte[]> ReceiveEvent;//将数据转到界面public void ReceiveMsg(IAsyncResult ar){//能进入这个事件,表明缓存中已存好本次的数据,不是通过BeginReceiveFrom来读取,BeginReceiveFrom是准备下次的int nRead = _server.EndReceive(ar);//获取传递过来的字节数。if (nRead <= 0|| realBytesRecv >= PagLength){realBytesRecv = 0;var Inforstr = "Socket rec33recv Error code:" + "\r\n";//出错return;}realBytesRecv += nRead;if (realBytesRecv >= PagLength)//接受完整,大数据字节包过来受网络限制,最大传递1472个字节,所以需要拼包{realBytesRecv = 0;buffIndex++;if (buffIndex > (MAX_BUFFLEN - 1))buffIndex = 0;Thread t1 = new Thread(ThreadReceiveEvent);t1.Start();}//必须加,为下次接受回调做准备_server.BeginReceiveFrom(recvBuff0[buffIndex], realBytesRecv, _readLen, 0, ref _remote, ReceiveMsg, null);}/// <summary>/// 获取网络字节包/// </summary>public void ThreadReceiveEvent(){var buffer1 = new byte[PagLength];var indx = buffIndex - 1;if (indx == -1)indx = MAX_BUFFLEN-1;Array.Copy(recvBuff0[indx], buffer1, PagLength);//复制接收数据,减去可能多余的数组ReceiveEvent.Invoke(buffer1);}#endregion#region 发送public bool SendMsg(byte[] value){var res = _server.SendTo(value, _remote);//会触发BeginReceiveFrom事件,好像是因为EndReceiveif (res < 0){return false;}return true;}#endregion/// <summary>///  // 获得本机局域网IP地址 /// </summary>/// <returns></returns>private string GetLocalIP(){IPAddress[] AddressList = Dns.GetHostByName(Dns.GetHostName()).AddressList;if (AddressList.Length < 1){return "";}return AddressList[0].ToString();}/// <summary>/// 获取本地有效的端口号/// </summary>/// <returns></returns>private string GetLocalValidPort(){IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();//返回本地计算机上的所有Tcp监听程序    var ipsTcp = properties.GetActiveTcpListeners();//返回本地计算机上的所有UDP监听程序     var ipsUdp = properties.GetActiveUdpListeners();for (int i = 1024; i < 5000; i++){foreach (var ip in ipsTcp){if (ip.Port == i) continue;foreach (var ip2 in ipsUdp){if (ip2.Port != i){return i.ToString();}}}if (i == 4999){return "";}}return "";}
}

使用方法:
连接:

BigDataUDPServerHelper uDPServerHelper = new BigDataUDPServerHelper("ip地址",int.Parse("端口号"), int.Parse("接收字节长度"));
uDPServerHelper.ReceiveEvent += Ss_ReceiveEvent;//接收字节事件
richTextBox1.AppendText("连接成功\n");

修改接收字节长度:

uDPServerHelper.SetBufferSize(int.Parse(textBox1.Text));

发送字节:

uDPServerHelper.SetBufferSize(6002);
byte[] code = new byte[] { 0x55, 0xaa,0x01,0x80,0x2b,0xf9,0x2f,0xd3,0xa1,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf3 };
var result = uDPServerHelper.SendMsg(code);
var str = result ? "发送成功\n" : "发送失败\n";
richTextBox1.AppendText(str);

接收字节:
在连接的时候,我们绑定了接收字节事件,此事件会在接收完整字节后触发,或者可找到帮助类中对应的位置修改传递方式。
考虑到高速大数据量,我在该接收函数中又添加了三维数组用于缓存,截图如下,因个人解析不同,故只用于参考:
ps:注意此处不能占用过多时间,会导致接收不完整。

写在最后:
和之前的upd通信相比,本次采用了异步通信的方式,但是这样的方式并不能说就实现了大数据量接收,因为数据到了,保存、解析、计算、使用都会占用时间,可能影响下次的接收保存。
所以我采用了二维数组缓存(二维数组不是一个整体的内存空间,是每个一维数组一个地址,所以不会造成读写使用一个对象 ),这样有32个一维数组可使用,将数据按条件存满一个第一个一维数组后,我使用下个一维数组进行保存,同时在线程中将第一个一维数组去进行解析、计算、使用,互不干涉。
同时在界面方面,也采用了多维数组进行缓存。
只有在每个环节都减少对象占用的等待时间,数据接收才能完整呈现。
最后,本有尝试添加一个接口,用于封装解析,但是发觉数据采集一段时间后出错,所以在不了解性能的情况下,尽量少一点封装较好。

c#实现Udp通信(四)--UPD大数据量接收(异步接收)相关推荐

  1. 解析四种大数据文件格式

    众所周知,Apache Spark支持许多种不同的数据格式,其中包括:无处不在的CSV格式.对于Web友好的JSON格式.以及常被用于大数据分析的Apache Parquet和Apache Avro. ...

  2. FinTech头条丨神州信息四项大数据产品成功通过权威测评认定

    近日,由赛迪传媒.中国大数据产业生态联盟等主办的"2020(第五届)大数据产业生态大会"在京举行,会上发布<2020中国大数据产业发展白皮书>,并揭晓"优秀大 ...

  3. 四说大数据时代“神话”:从大数据到深数据\n

    作为国内最大的电商平台之一,苏宁每天要处理数量巨大的数据.为了更快速高效地处理这些数据,苏宁调度平台采取了哪些措施呢? 本文是苏宁大数据离线任务开发调度平台实践系列文章之上篇,详解苏宁的任务调度模块. ...

  4. 四说大数据时代“神话”:从大数据到深数据

    在机器学习方面始终有个基础性的误会,即更大的数据会形成更快的学习效果.殊不知,更大的数据并非意味着能发现更深刻的信息.事实上,与数据的规模相较,数据的质量.价值和多样性更最该关注,即数据的" ...

  5. 【送书福利-第四期】从程序员到架构师:大数据量、缓存、高并发、微服务、多团队协同等核心场景实战书籍

    大家好,我是洲洲,欢迎关注,一个爱听周杰伦的程序员.关注公众号[程序员洲洲]即可获得10G学习资料.面试笔记.大厂独家学习体系路线等-还可以加入技术交流群欢迎大家在CSDN后台私信我! 送书福利-第四 ...

  6. Qt TCP通信readAll()读取接收数据时无法读完大数据量的解决法案

    在测试利用TCP传输图片的时候,服务器使用Qt的TCP类库.在TCP接收槽函数中使用readAll()成员函数的时候发现readAll()并不能读取全部的数据,比如,在客户端发送一张2MB的图像,但是 ...

  7. 物联网与大数据(四)大数据技术 物联网操作系统

    前言 关于物联网与大数据的分享已经迎来最后一期,回顾之前的内容:我们在物联网与大数据(一)中介绍了物联网与大数据的含义.背景:在从物联网看大数据中探讨了物联网形成大数据的主要环节:在从大数据看物联网中 ...

  8. 大数据导论(四:大数据的存储)

    1.面临的挑战 1.1系统问题 面对大数据的爆炸式增长,且具有大数据量.异构型.高时效性的需求时,数据的存储不仅仅有存储容量的压力,还给系统的存储性能.数据管理乃至大数据的应用方面带来了挑战. 1.2 ...

  9. 【Apache POI】Excel操作(四):Excel大数据量的写入

    迷茫代表着你身边还有选择,焦虑意味着你手上还有时间. 有目录,不迷路 前言 超量数据 速率比较 原因剖析 超级版本大救星 往期回顾 前言 之前在下面这期Excel操作: [Apache POI]Exc ...

  10. 高并发高可用处理大数据量

    教学大纲: 教学内容 大型互联网三大问题-高并发,高可用,大数据量 第一天内容如下: 1:什么是高并发? 2:为什么要解决高并发 3:画图分析:1) 多用户访问单台App服务器及数据库时,性能分析,瓶 ...

最新文章

  1. ubuntu 下安装 VIM 依赖vim-common错误
  2. form提交后台注解拿不到数据_Form表单详解
  3. jzoj6286,P4442-走格子(Portal)【BFS,SPFA】
  4. java 数据结构详解,数组,集合,HashMap
  5. 莫侵残日噪,正在异乡听
  6. MySQL性能调优与架构设计——第11章 常用存储引擎优化
  7. 再发Wallop和GMail邀请各4个!
  8. 文言文编程可以编译成PHP吗,PSTK项目:文言文也能编程?大四学生发明文言文编程语言...
  9. 超高精度UWB其实并不贵——UWB定位基站成本详解
  10. android switch 使用
  11. 使用伪类实现划掉字体
  12. App 后台架构设计方案 设计思想与最佳实践
  13. [乐意黎转载]从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式
  14. 计算机原理74181芯片,利用SN74181芯片构成16位ALU及原理.ppt
  15. 2021-06-03 一只小小白K 期许未来!
  16. 镗孔指令g76格式_关于镗孔G76循环退刀方式总结
  17. 如何提取视频中的音频,这个方法真的很简单
  18. STM32WB55_NUCLEO开发(2)----使用STM32CubeMX 生成的简单 BLE 应用程序连接手机APP
  19. 千亿级金融场景下,基于Pulsar的云原生消息队列有怎样的表现?
  20. moon服务器 zerotier_配置ZeroTier的moon服务器记录

热门文章

  1. 图的最短路径之Dijkstra算法
  2. windows中postman中文版安装
  3. ERP系统中BOM的作用
  4. 一窥Memory测试算法及自我修复机制
  5. 内窥镜胶囊(胶囊内镜)硬件方案(二)
  6. c++实现植物大战僵尸修改器
  7. mysql查询当月过生日_MySql查询本周/月或下周/月过生日的人
  8. 二元二次拟合 matlab函数
  9. 层次分析法和多属性决策算法
  10. jquery-seat-charts 使用-自定义座位号 及 重新加载数据