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

erosna 2015-03-12 10:44:15
同步加线程
使用事件并发处理接收到的数据
public void SyncRecive()
{
Task listen = new Task(() =>
{
while (true)
{
int length = connect.ReceiveFrom(this.packetBuffer, 0, this.packetBuffer.Length, SocketFlags.None, ref this.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();
}

异步

public void AsynRecive()
{
connect.BeginReceiveFrom(this.packetBuffer, 0, this.packetBuffer.Length, SocketFlags.None, ref this.remoteEndPoint, new AsyncCallback(AsynReciveCallback), null);
}

private void AsynReciveCallback(IAsyncResult asyncResult)
{
if (asyncResult.IsCompleted)
{
int length = connect.EndReceiveFrom(asyncResult, ref this.remoteEndPoint);
byte[] packet = this.packetBuffer.Unpack(length);
this.counter++;
if (this.ReceiveData != null)
{
this.ReceiveData(packet, this.remoteEndPoint, null);
}
}
this.AsynRecive();
}

同步加线程接收效率明显高于异步
这样的情况下使用异步还有优势吗?


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

110,532

社区成员

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

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

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