UDP 接收数据同步 异步选择问题

问题描述

同步加线程使用事件并发处理接收到的数据publicvoidSyncRecive(){Tasklisten=newTask(()=>{while(true){intlength=connect.ReceiveFrom(this.packetBuffer,0,this.packetBuffer.Length,SocketFlags.None,refthis.remoteEndPoint);byte[]packet=this.packetBuffer.Unpack(length);if(length!=active.Length||packet.ToMessage()!=active.ToMessage()){this.counter++;if(this.ReceiveData!=null){this.ReceiveData(packet,this.remoteEndPoint,null);}}}});listen.Start();}异步publicvoidAsynRecive(){connect.BeginReceiveFrom(this.packetBuffer,0,this.packetBuffer.Length,SocketFlags.None,refthis.remoteEndPoint,newAsyncCallback(AsynReciveCallback),null);}privatevoidAsynReciveCallback(IAsyncResultasyncResult){if(asyncResult.IsCompleted){intlength=connect.EndReceiveFrom(asyncResult,refthis.remoteEndPoint);byte[]packet=this.packetBuffer.Unpack(length);this.counter++;if(this.ReceiveData!=null){this.ReceiveData(packet,this.remoteEndPoint,null);}}this.AsynRecive();}同步加线程接收效率明显高于异步这样的情况下使用异步还有优势吗?

解决方案

解决方案二:
同步线程模式完全没有IAsyncResult对象的问题是这个原因速度提高了吗
解决方案三:
我不知道你所谓的效率更高是如何得出的结论如果你是说单纯从某一次访问(只有一个客户端进行访问),同步响应速度更快的话,这说明不了什么的还是拿我经常举的例子来说:假如你是等快递,你自己站门口等当然比门卫收到快递给你打电话会更快那么一点点,但是这只是你一个人的情况如果有100个客户端去访问你的服务端,好比有100个人要收快递,你不可能让100个人都跑到门卫去排队等吧?
解决方案四:
如果是10000个人要收快递呢?很明显只让一个人在那里等,来了谁的快递就给谁打电话来取,单纯从某一个人来说,可能不如他自己在那里等更快,但是总体上来说,更节约资源,也能够响应更多的请求,而不至于超过10个人就把门卫塞满了
解决方案五:
你说的这个我明白TCP(会出现你说的100个人要收快递,UDP不会吧无连接)肯定是异步好因为并发N个连接我这样做就要有多少连接就开多少线程(线程下还要并发事件)UDP接收的时候就是对一个端口死循环接收不存在连接(虽然也可以建立连接可连接以后就变1对1了)同步接收是这样的来了快递---->个人站门口(并发事件N个人站这个人后面)---->>>循环异步来了快递---->电话(IAsyncResult)------>收快递(并发事件N个人站这个人后面)---->>>循环
解决方案六:
UDP其实也差不多的虽然是面向无连接的,那么同步就是派一个人在那等,等到了他就拿着快递给别人送去,送完再回去等而异步就是让门卫等,来了快递给别人打电话,别人接到电话再自己来取可能差别并不像TCP通信那么大包括客户端TCP通信,用同步还是异步差别也并不大,而且异步反而不容易控制逻辑顺序
解决方案七:
我做的是事件模式,一个人收到快递后会触发事件(这里其实也算是异步),这个事件去处理收到的数据包这个人只负责收快递触发事件触发事件以后就继续收快递异常实际上也要在收到快递以后触发同一个事件(数据收到肯定要做各种处理)
解决方案八:
主要是感觉用异步多了一个打电话的过程。(系统要做资源分配等各种操作)我这个异步接收也是多级并发,异步的接收也是收到快递以后继续并发事件不去跟踪收到的快递怎么处理。
解决方案九:
我测试了收到数据后操作界面,全部接收完毕后界面会卡很久并发了近100W次的界面操作使用同步、异常的差距就在UDP缓存因为接收数据速度不一样,局域网急速发速度的时候整个缓冲区一下就被填满导致信息覆盖connect.ReceiveBufferSize=ReceiveBufferSize;默认好像是8K同步模式能基本保证客户端发送一条,服务器基本能马上接收到并发出界面操作事件。异步会因为缓冲区被覆盖导致丢失大量信息。
解决方案十:
各有利弊吧你实际上就是实现了系统给你封装好的异步的功能而已代价就是有一个线程必须在那里等待还拿快递来说,好比是派个门卫一直在那干等,还是说门卫本身也可以该干啥干啥,快递来了按门铃,门卫才去看,而已
解决方案十一:
我是初学者,不知道理解对不对。
解决方案十二:
最终就是数据到底在哪里排队的问题,是在你自己定义的线程里排队,还是在系统缓冲区里排队如果只有一个快递要来,可能同步和异步就没啥大区别而如果有非常多的快递要来,同步的方式就是来一个收一个,快递先放到门卫室排队,然后等着别人来取而异步的方式就是送快递的在大街上排排站,等着门卫来取
解决方案十三:
关键问题是如何处理粘包分包的问题用异步的方式可能比同步更难处理一些,但是绝对不是说异步本身性能上有问题导致数据丢失很有可能来了两个快递,但是门卫一次性收到了,那么你如何区分它是应该给2个人的,而不要给同一个人了也有可能某个人今天要来3个快递,但是不是一起来的,而是分别送了3次才送来的
解决方案十四:
嗯嗯就是这个意思,我理解应该是没错。因为缓冲区大小问题用异步要设置的很大(我测试的比较暴力,几台机器每秒10W个小数据包发送)用异步缓冲区必须设置的很大才能保证数据不被覆盖(同意拿100W个包比同步慢40%)同步少了IAsyncResult开销缓冲区有数据时拿走的快。
解决方案十五:
UDP本来就是不可靠协议,而且UDP的包一般不会粘包的吧(不会像TCP把各种小包打包到一起发送,就算1个字节UDP也是一个包发过来),退一步说不管怎么做这些都要处理(并发的事件)而且(UDP我打算是做信息传递,不发送大于1400的信息)我只是觉得单纯说接收数据包速度而言同步+线程的模式比直接使用异步方法效率更高。
其他方案:
也有可能某个人今天要来3个快递,但是不是一起来的,而是分别送了3次才送来的this.ReceiveData(packet,this.remoteEndPoint,null);this.remoteEndPoint可以当作是人packet可以在里面添加信息表示要三个包都到了才是完整。
其他方案:
这个主要还是看业务需求来取舍吧既然提供了同步和异步两种方式,就都是有各自的作用的不是说用异步就可以完全代替同步了有些时候该用同步还是要用同步
其他方案:
感觉为了保证收到全部的快递还是同步的好。后台能不能处理完是一回事,感觉还是比快递丢了好。异步的时候随着快递包的增加缓存区需要几何倍数增加才能保证所有快递不被挤掉。(虽然这样的情况不太可能,只是单纯的测试)
其他方案:
3.5提供的SocketAsyncEventArgs类好像也降低了IAsyncResult的开销来提高效率
其他方案:
我还测试了并发事件的时候先并发事件--->回调线程池会按照接收到的数据次序处理界面,先回调--->并发事件线程池会把接收到的数据次序打乱处理界面,
其他方案:
把包编上号,测试下看看会不会丢包再说?我也不太清楚,反正当初单独用事件触发来处理还是会少包,而用事件触发后再异步把内容交给别人处理就好多了
其他方案:
引用8楼erosna的回复:

我测试了收到数据后操作界面,全部接收完毕后界面会卡很久并发了近100W次的界面操作使用同步、异常的差距就在UDP缓存因为接收数据速度不一样,局域网急速发速度的时候整个缓冲区一下就被填满导致信息覆盖connect.ReceiveBufferSize=ReceiveBufferSize;默认好像是8K同步模式能基本保证客户端发送一条,服务器基本能马上接收到并发出界面操作事件。异步会因为缓冲区被覆盖导致丢失大量信息。

你终于拿出一些具体的东西来问了。实际上如果按照你说的“同步处理快、异步处理慢”,那么你也就看不到什么“丢失大量信息”的问题了。反之,正由于你的程序在并发处理时有bug而丢处理,并且异步系统的处理速度比你认为以为得更快许多,所以你才会搞不定的。同步、阻塞、循环,程序运行得很慢很卡,所以你才会觉得你的程序“稳定”。这时侯你应该好好看看你的程序设计问题。一般人都知道,当他异步、并发处理时,往往再写的有bug时会“丢失数据操作”,所以他就会努力找到自己的程序bug,而不会去怪“异步并发程序运行太慢所以丢数据”的。
其他方案:
嗯咯我大概总结出来了,不管同步异步,始终高强度接收数据包的情况下如果来不及处理收到的数据包(收包,后台处理)。在程序内部并发数越来越多导致并发达到极限,内存CPU需求急剧上升最终-----》程序卡死缓冲区覆盖未处理的数据包---》丢包,程序内部处理不及时也会导致最终------》程序卡死不管怎么样一个程序总有一个处理极限,达到这个极限就会出现问题。。。只能根据实际应用,网络情况来判断程序能不能承受。
其他方案:
引用22楼erosna的回复:

嗯咯我大概总结出来了,不管同步异步,始终高强度接收数据包的情况下如果来不及处理收到的数据包(收包,后台处理)。在程序内部并发数越来越多导致并发达到极限,内存CPU需求急剧上升最终-----》程序卡死缓冲区覆盖未处理的数据包---》丢包,程序内部处理不及时也会导致最终------》程序卡死不管怎么样一个程序总有一个处理极限,达到这个极限就会出现问题。。。只能根据实际应用,网络情况来判断程序能不能承受。

是的.代码使用不同的方式,可能对性能产生影响,但是终究会有极限的
其他方案:
不考虑代码质量太差的情况,只考虑正常的应用中要么是用空间换时间,也就是要速度快,占内存和CPU资源就要多要么是用时间换空间想两个都提升,代码优化的空间毕竟有限,升级硬件才是根本的解决之道台式机到极限了,就换服务器,服务器到极限了,就换服务器组

时间: 2024-12-28 19:01:22

UDP 接收数据同步 异步选择问题的相关文章

通过异步方式发送和接收数据(tcp异步收发数据)

服务端 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.Threa

socket UDP接收数据问题!

问题描述 有个问题请教大家一下,socketUDP不是无连接的吗,为什么写了一个demo,客户端向服务器发送数据,收到后又发送答复数据回客户端,但有一点很奇怪,我写的服务器发送后,手动点击客户端上面的接收,也就说接收在服务器发送之后,为什么还是可以收到?这种不应该就是丢包么?应该是先循环接收,然后阻塞到接收方法,服务器发送过来才可以收到吧,而我是先发送,然后在手动点击进入接收方法,还是可以收到,奇了怪了 解决方案 解决方案二:socket有接收缓存,你客户端的UDP不是已经开始服务了吗?解决方案

第二人生的源码分析(三十一)接收数据的流量控制

数据接收回来后,本来就应立即处理掉,这样是比较简单的想法.但由于网络带宽有限,这时就需要限制UDP接收数据的速度.下面就来分析这种需求的实现,它的代码如下: #001 S32 LLPacketRing::receivePacket (S32 socket, char *datap) #002 { #003      S32 packet_size = 0; #004    下面判断是否使用接收的流量限制. #005      // If using the throttle, simulate

C#多个ip数据接收和同步的问题

问题描述 C#多个ip数据接收和同步的问题 我用C#编写数据解析的代码,情况是:有40或更多个ip向软件发送udp数据,软件需要将不同ip的有相同编号的数据组合起来,每个ip数据发送频率为600HZ,请问这种情况如何处理,有没有有借鉴的源码? 解决方案 这种raw socket层的代码,还是用C++去写比较好.github上有很多开源的项目.

java nio socket 异步接收数据

问题描述 nio socket 异步接收数据,如何确定收接的数据,就是发送的返回的?有谁研究过没. 问题补充:如果不用id,nio客户端是否可以同步接收数据呢?是把socketChannel.configureBlocking(true)吗? 解决方案 在消息中增加UUID,在调用端记录UUID,并将UUID和消息一起发送到服务端,服务端的回传消息附件上UUID,调用端根据收到的消息包含的UUID确定给哪个调用者.解决方案二:异步调用的常见问题.因为没有办法实施返回,只有打标志了.要你把通信协议

数据同步-C/S架构的数据库异步同步问题

问题描述 C/S架构的数据库异步同步问题 开发语言:C# 数据库:sql server 想实现功能: 把服务器上的数据库down到本地,客户端使用时操作本地数据库,固定时间或服务器数据库连通的情况下,将本地数据同步到服务器的数据库中. 目的:在服务器关闭.或断网情况下,可以保证客户端使用的稳定性. 希望大神们指点迷津,提供一些可行性方案,十分感谢! 解决方案 关键看你的业务需求. 比如说电子词典完全可以离线工作,在线更新词库. 但是银行卡pos刷卡就绝对不能离线工作. 没有什么一劳永逸的办法,你

参数-jsp页面从服务器接收数据,并且将数据经选择后提交到服务器

问题描述 jsp页面从服务器接收数据,并且将数据经选择后提交到服务器 jsp从servlet接收了一个数组,想利用select让用户选择后将选择后的结果提交回servlet,结果在向servlet提交过程中参数一直传不过去,求大神帮忙解决一下 <! --classselect.jsp--> <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

ava-如何使用UDP实时接收接收数据?

问题描述 如何使用UDP实时接收接收数据? DatagramSocket ds = new DatagramSocket(10000); byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf0buf.length); ds.receive(dp); String data = new String(dp.getData() 0 dp.getLength()); ds.close(); 上面的代码可以接收UD

怎样把udp接收到的数据再转发给其他客户端??

问题描述 怎样把udp接收到的数据再转发给其他客户端??最好给哥接收再转发的例子,谢谢! 解决方案 解决方案二:路过帮顶=============11月6日,论坛升级公告,积分已经做了调整!http://topic.csdn.net/u/20081107/11/b27dc75f-14b1-4594-9de3-5b18d9e36a11.html此次调整增加了两个新的可用分获取渠道:1:帖子被推荐(加精)后,帖主可以获得88分的可用分奖励:2:帖子结帖后会返还帖主50%的悬赏分,无满意结帖不返还分数