怪问题,求高手帮解决!!多线程中丢数据的问题

问题描述

【背景介绍】:本人原来开发了一套多通道数据采集分析系统,分析软件开发环境是VS2010,.Net4.0,使用C#语言编写,配合NImeasurementstudio2010做图形显示,另外还用了DXPerience10的控件。多通道采集器通过UDP协议与软件进行数据通讯,软件和采集器有一套完善的通讯协议,通讯过程是这样的,软件发送数据请求包,采集器将所有24通道数据发送给软件(24包)。为保证数据完整性,软件存储策略是收到全部数据后才同意存储,否则丢弃数据,等到下一帧数据。该软件也开发完成较长时间,软件在【正常笔记本】上运行正常,win732位64位xp下都没问题。【遇到的问题】本次想继续升级采集器,在采集器内部集成了一个【工控机模块】,安装了64位Win7,和正常电脑用起来没什么区别,用的是AtomCPU,软件直接在里面运行,可以脱离笔记本采集存储数据。但是在原有软件和通讯协议未改动的情况下,发现软件在新采集器运行是实时数据显示卡顿,经常三四秒才更新数据(正常通讯是每秒请求一次数据,相应界实时数据显示也是每秒更新),起初怀疑工控机的CPU图形处理能力较差,导致界面不更新,但通过更深入的排查,发现是多线程丢包了。具体判据如下:(1)用抓包软件查看网络收发情况,发现通讯流畅不存在网络丢包的情况。(2)在软件中添加相应代码监测实时数据情况发现,问题是由于负责接收数据的线程丢失数据,导致未收到完整24通道数据,软件存储策略将这一帧的数据丢弃所致。丢失数据的情况比较随机,正常共24包数据,每次丢数据时收到数据从十几包到23包不等。(3)将线程中等待数据的时间延长,依然无法等到数据,确实是没了,不是迟了。。。【目前所做的努力】除上面所说监测代码运行情况抓包等工作外,本想将开发环境包括.net环境升级到更高版本,无奈配合使用NImesurementStudio新版本的资源比较难找,暂时还没升级。另外,原软件是在32位环境下开发的,编译成64位后也没啥改观。【相关代码】(1)主线程中等待数据代码while(true){try{allData=newbyte[ChannelCount][];receivedCount=0;//请求数据Send(reqBuffer);CanReceive=true;//开始接收intwaitTime=0;boolbOutTime=false;Thread.Sleep(6);while(receivedCount<ChannelCount)收到数据不够24通道就不处理{Thread.Sleep(40);waitTime++;Debug.WriteLine("等待中"+DateTime.Now.ToString()+"-"+DateTime.Now.Millisecond.ToString()+"waittime"+waitTime);if(waitTime>10){bOutTime=true;break;}}(2)子线程中处理数据部分代码,子线程是在主线程中开启的publicstaticvoidReceiveThreadRun(){byte[]receivebytes;while(true){try{if(!CanReceive)Thread.Sleep(2);receivebytes=Receive();while(receivedCount>=allData.Length&&CanReceive)Thread.Sleep(2);try{allData[receivedCount]=receivebytes;}catch(Exceptionex){}boolrs=处理协议数据(receivebytes);if(rs)receivedCount++;(3)子线程(2)中接收数据代码如下privatestaticbyte[]Receive(){byte[]re;MainForm.MaiInstance.网络状态=Status.Running;re=udpClient.Receive(reflocalEndPoint);//接收数据代码MainForm.MaiInstance.网络状态=Status.DarkRunning;returnre;}对代码运行情况的监测最深就带这里,丢数据时监测这里运行情况就收不到数据了目前就是以上的情况,望各位大神不吝赐教,先谢过了

解决方案

解决方案二:
看到udpClient,问题就解释的通了你用udp传输,包全丢光也是正常现象,哪里算怪问题要么换tcp,要么自己做重发机制
解决方案三:
引用1楼shingoscar的回复:

看到udpClient,问题就解释的通了你用udp传输,包全丢光也是正常现象,哪里算怪问题要么换tcp,要么自己做重发机制

的确是
解决方案四:
UDP是无状态协议,只管发送,并不管对方是否收到所以丢失数据是常态,不丢失是运气
解决方案五:
个人觉得首先应该把数据接收和数据解析分离,数据接收线程接收数据后把数据放入缓存(或线程安全的容器),然后快速返回,数据拼包和解析放到另外的线程中去。否则不是你接收不到,而是处理速度跟不上,表现为数据接收不全。
解决方案六:
sorry,还以为是tcp,原来是udp,撤回4楼的回复
解决方案七:
感谢大家回复,当初考虑到采集器芯片的处理能力,udp效率高点,另外是的单独的局域网,网络环境较好,所以选的udp之前都很好,就是换这个集成的计算机就不行了我抓包软件看到数据包已经到达网卡了,但是程序udp接收那里没了,这能完全说是用UDP协议的问题吗?
解决方案八:
引用6楼allen421的回复:

感谢大家回复,当初考虑到采集器芯片的处理能力,udp效率高点,另外是的单独的局域网,网络环境较好,所以选的udp之前都很好,就是换这个集成的计算机就不行了我抓包软件看到数据包已经到达网卡了,但是程序udp接收那里没了,这能完全说是用UDP协议的问题吗?

那是处理不过来了,数据就会丢掉,可以通过增加ReceiveBufferSize来优化不过不管你怎么弄,udp丢包是必然的
解决方案九:
4楼说得对,应该开一个死循环线程收udp包,记录接收包数,测试一下会不会丢包。理论上会丢,但在工程实践中,300mbps没问题。不要人云亦云,测试结果说话。
解决方案十:
都是扯淡,谁说UDP就要丢包,开始接收必须要异步,并且循环,代码里面那么多Sleep,怎么可能正好是非Sleep状态收到数据包,Tcp还是黑receivebytes=Receive();必须改异步,然后在endinvoke里面写结果处理
解决方案十一:
楼上那么多人,竟然讨论那么激烈,一群蠢蛋,当前线程一会Sleep一会正常工作,对方咋知道你这时候是在Sleep还是工作?必须加异步轮询,还UDP丢包不奇怪。。。。。太无知了
解决方案十二:
为什么不用异步,while(true)用信号量控制。
解决方案十三:
楼上的那些水货不用看了,直接贴上去抄吧,监听必须时刻等待对方发送内容,接收线程不能有任何Sleep,处理里面可以有,监听线程你认为正确的Sleep可能这个时候对方发了内容,可能就几十毫秒,即使你Sleep了几毫秒,也会丢数据http://cn.bing.com/search?q=udp+%E5%BC%82%E6%AD%A5+c%23&go=%E6%8F%90%E4%BA%A4&qs=n&form=QBRE&pq=udp+%E5%BC%82%E6%AD%A5+c%23&sc=0-7&sp=-1&sk=&cvid=A84DCB1E360B473A9ECF6523B64E80B2

时间: 2024-10-01 01:23:06

怪问题,求高手帮解决!!多线程中丢数据的问题的相关文章

sql server-SQL Server提示错误,求高手帮解决

问题描述 SQL Server提示错误,求高手帮解决 select gl.ccus_id 客户编码, gl.cexch_name 币种, gl.cbegind_c 金额期初方向, (case when gl.cbegind_c = '借' then SUM(ISNULL(gl.mb, 0)) + SUM(ISNULL(ap.iAmount_f,0)) - SUM(ISNULL(dts.iQuantity * dts.iTaxUnitPrice, 0)) else sum(isnull(-gl.m

跪求高手出现-求高手帮帮忙,不知道该怎样解决

问题描述 求高手帮帮忙,不知道该怎样解决 Exception in thread "main" java.lang.StackOverflowError at java.text.DecimalFormat.subformat(DecimalFormat.java:903) at java.text.DecimalFormat.format(DecimalFormat.java:692) at java.text.DecimalFormat.format(DecimalFormat.j

eclipse+gradle build过程中出现此问题 求高手帮忙解决下

问题描述 eclipse+gradle build过程中出现此问题 求高手帮忙解决下 Execution failed for task ':PunkHoo:packageAllDebugClassesForMultiDex'. java.util.zip.ZipException: duplicate entry: android/support/v4/internal/view/ SupportMenu.class

VS2012的Windows Service程序打包成exe后安装,但是在进程管理中找不到这个服务,是怎么回事呢???求高手帮忙解决,谢谢!!在线等……

问题描述 VS2012的WindowsService程序打包成exe后安装,但是在进程管理中找不到这个服务,是怎么回事呢???求高手帮忙解决,谢谢!!在线等-- 解决方案 解决方案二:windowsservice安装过程中,不光是复制可执行文件,很关键的一步是需要自定义的,就是注册服务,并且启动服务.注册要用到installutil,启动就用netstartxxxxxx解决方案三:我是用这种方法配置打包的,以前有个项目也是按这种方法配置打包成功运行没有问题,不知道这次是怎么回事http://bl

html5-【菜鸟问题】两组轮播JS代码有冲突,问题很多!求高手帮忙解决

问题描述 [菜鸟问题]两组轮播JS代码有冲突,问题很多!求高手帮忙解决 上图JS代码如下: [code=javascript] //首页顶部轮播 var i = 0; jummper(); function jummper() { $(".car ul li").eq(i).find("img").css("left", "-100%"); //滑动图在左边-100%准备 $(".car ul li").e

php字符串转换-php 字符串转换为题,求高手帮看看那里有问题?

问题描述 php 字符串转换为题,求高手帮看看那里有问题? Date.prototype.format = function(format){ var o = { "M+" : this.getMonth()+1, //month "d+" : this.getDate(), //day "h+" : this.getHours(), //hour "m+" : this.getMinutes(), //minute &quo

json- 公司给的任务,求高手帮我

问题描述 公司给的任务,求高手帮我 假如有一个json数据接口,例如http://api.esportsmh.com/CourtPoints.aspx?key=itihcxtuxc&a这是一个接口,里面装的是json数据,求怎么让json数据显示出来,静态页面实现出来!jquery+一般处理程序解决 解决方案 我最近也在做这个,但是我不是用jQuery实现的,我是直接用C#获取返回值,然后将返回值处理一下,变成JSON格式,然后再转化为一般对象!供你参考:protected void btnSe

Developer可以正常连接到远程数据库,单tomcat的项目里却连接不上,求高手帮忙解决。

问题描述 我的Developer配置监听,连接VPN可以远程访问到数据库.但是我启动tomcat里面的项目却访问不了远程的数据库,SqlMap文件里的连接配置完全没问题.求高手帮忙解决啊. 解决方案 解决方案二:还是检查连接配置.解决方案三:你怎么访问的至少贴出来看下吧,报错吗?还有配置也发一下看看解决方案四:报错信息贴出来兄弟们才能帮你分析解决方案五:连接不上至少有个反馈吧

基础 发散-真心的求高手帮我看看代码,指教下,我很困惑

问题描述 真心的求高手帮我看看代码,指教下,我很困惑 命题:求求1+1/2+1/3+--+1/n的c语言编程 以下是我的代码: #include void main() { float i,j,sum; printf("请输入你想求的位数:n"); scanf("%f",&j); for(i=1;i<=j;i++) { sum+=1/i; } printf("结果为 %fn",sum); } 运行结果不对,但是我觉得思路很清晰,找不