UDP怎么判断接收数据完毕

m0_37646670 2019-02-12 07:39:48
一个线程接收数据
一个线程处理数据

在处理数据线程里,我想判断UDP接收完毕,然后开启另个线程去判断接收的数据是否完整
需要重发包序号。

可是一直判断不好。。常常包没收完 就要服务器重发了,导致很浪费
...全文
2011 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_45615943 2021-09-14
  • 打赏
  • 举报
回复

麻烦问一下 问题解决了吗 我现在也遇到同样的问题

threenewbee 2019-02-17
  • 打赏
  • 举报
回复
udp本身不能判断,但是你可以先发一个文件长度,再发实际数据。或者发送完数据,再发一个特殊的标记作为结束符
xjl7488562 2019-02-17
  • 打赏
  • 举报
回复
其实udp如果你的处理数据那块没有问题其实不需要做数据校验,你要做校验就用tcp吧
  • 打赏
  • 举报
回复
一般来说纠结 udp 的”可靠“通讯比较荒唐。这为什么不用 tcp 呢? 使用 udp 基本上来说,就是因为通讯的内容并不是很重要,丢了就丢了。反正业务上会有比较粗放的补救流程。
  • 打赏
  • 举报
回复
实际上,大部分 udp 通讯是不用纠结什么重发的。重发纯粹是一个业务行为,也就是从技术上来说,udp丢了消息就丢了,用不着重复发。只有你的业务上花费巨大代价设计业务规则时才考虑重发,udp 重发其实并不是一个常见地通讯方式。 比如说,如果没有收到一个基站的上报信息,那么可能过10分钟就重发3次提醒信息,提醒对方有多久没有上报信息了。
  • 打赏
  • 举报
回复
引用 楼主 m0_37646670 的回复:
一个线程接收数据 一个线程处理数据
应该学会专业一点儿的异步概念。消息到来的时候自然就会触发回调委托(事件处理),消息没到来的时候就没有占用任何“线程”。哪里来的两个(或者3个)线程“?运行时占用0个、1个、5个、20个线程都有可能,你怎么可能知道要用几个线程来处理通讯?
引用 楼主 m0_37646670 的回复:
在处理数据线程里,我想判断UDP接收完毕,然后开启另个线程去判断接收的数据是否完整 需要重发包序号。 可是一直判断不好。。常常包没收完 就要服务器重发了,导致很浪费
udp 不是像 tcp 那样的流式通讯,而是块儿式通讯。所以生搬硬套 tcp 是非常错误的。什么叫做”在处理数据线程里判断udp接收完毕“?接收端根本收不到数据,重发动做是基于发送端主动行为,不是什么被动行为。
angel6709 2019-02-15
  • 打赏
  • 举报
回复
定义协议
wanghui0380 2019-02-13
  • 打赏
  • 举报
回复 1
ps:udp不保证收取顺序,所以你不太可能做什么最后一包的判定。我们通常只能说要么每一包都确认,要么设计成多长时间内该session没有数据接收认为完毕然后进行验证完整性。如果不完整再要求对方发送。
wanghui0380 2019-02-13
  • 打赏
  • 举报
回复
udp在数据量不超过最大值前,一个包就是一个包不会产生粘包。所以无需特殊处理
而通常情况下选用udp协议的包都比较小,所以无需判定是否接收完毕。
如果你要发的数据比较大,通常自己设计封包协议和分包,这个时候需要根据自己协议去判定(当然因为udp其实只管发,不管收,所以如果数据大,使用udp你还需要自己设定接收确认和重发,so,如果数据大而且必须保证接收正确的情况,请使用tcp而不是使用udp)
  • 打赏
  • 举报
回复
不建议使用udp做可靠通讯,可靠通讯用tcp发,udp作为广播接收通讯使用。
loveljy_19901114 2019-02-13
  • 打赏
  • 举报
回复
引用 2 楼 m0_37646670的回复:
比方说服务器发来100个包,我收完数据再检查少哪几个包
可现在 我是收到20个包 我就去检查了 然后又让服务器重发了80个包。。
你这个收到20个包就去检查这个动作是怎么触发的
xian_wwq 2019-02-13
  • 打赏
  • 举报
回复
udp要可靠,得附加应答确认信息
客户端不能只顾发,
得根据server的应答信息决定重发还是继续。
如果对数据可靠性高,不建议一次发送很多包。


失落的神庙 2019-02-13
  • 打赏
  • 举报
回复
0[包索引]100[分包长度]100[本次分包大小]899989[包总大小]xxxxx[分包内容] 其它的自己加。这样客户端判断所有包师傅接收完成 每个包可放不同线程。可以使用锁。线程处理完这个分包再进行重试或者完成获取下个分包。所有线程结束后进行检验。
wanghui0380 2019-02-13
  • 打赏
  • 举报
回复
本来udp就是设计给实时系统--------数据小,频率快,偶尔丢1,2包(或延后1,2包)无影响的地方用的

比如发送cpu,内存监控这种小数据,他要的就是实时数据(当下的数据)--偶尔丢1,2包没啥关系,只要后一个包到了,前面的数据就可以扔了,所以设计要求上就是简单,快速,无需多余验证(其实正常也需要验证,因为他会乱序,所以正常我们会有一个byte的索引顺序)

而你的要求是大数据并且不丢包,本身就不是udp的设计目标,所以你就得自己把握手,传输顺序校验给加上。当然这不如直接使用tcp了
m0_37646670 2019-02-13
  • 打赏
  • 举报
回复
引用 11 楼 wanghui0380 的回复:
上面说的都没有任何用处,无论是你自己的判定队列为空,还是后面说一共有多少包。

因为udp本质上就是他就是拿掉了握手和传输顺序校验的tcp,所以他本身就不保证一定能收到,也不保证收到的顺序一定是发送的顺序。

so如果一定是udp,就只有2条路
1.采用每包验证方式,发送端每包都需要客户端确认,超时没确认的他自己重发(不需要你去提醒),重发多少次依旧无确认,发送端认为失败,记录日志
2.发送端不管确认,那么需要在接收端设置超时,比如我规定这个session没达到总包数,并且收到的最后一个包后多长时间没有收到其他包了,引发重发申请机制


嗯 我去试试
wanghui0380 2019-02-13
  • 打赏
  • 举报
回复
上面说的都没有任何用处,无论是你自己的判定队列为空,还是后面说一共有多少包。

因为udp本质上就是他就是拿掉了握手和传输顺序校验的tcp,所以他本身就不保证一定能收到,也不保证收到的顺序一定是发送的顺序。

so如果一定是udp,就只有2条路
1.采用每包验证方式,发送端每包都需要客户端确认,超时没确认的他自己重发(不需要你去提醒),重发多少次依旧无确认,发送端认为失败,记录日志
2.发送端不管确认,那么需要在接收端设置超时,比如我规定这个session没达到总包数,并且收到的最后一个包后多长时间没有收到其他包了,引发重发申请机制
  • 打赏
  • 举报
回复
我觉得你可能需要在每个包中标记该包的顺序,本次发送总共有多少个包
loveljy_19901114 2019-02-13
  • 打赏
  • 举报
回复
引用 8 楼 m0_37646670 的回复:
[quote=引用 4 楼 loveljy_19901114 的回复:] [quote=引用 2 楼 m0_37646670的回复:]比方说服务器发来100个包,我收完数据再检查少哪几个包 可现在 我是收到20个包 我就去检查了 然后又让服务器重发了80个包。。
你这个收到20个包就去检查这个动作是怎么触发的[/quote] 我有个队列用来存接受到的数据,然后在处理线程里处理一个包删除一个, 这个队列一边在加数据,一边在删除,我现在是当队列没数据了我就去检查收到的数据完整性 但似乎有时会处理完数据了 UDP包还没收到 导致进入检查数据确认重发包了 [/quote] 你这个思路不对,不能说队列里面没数了你就认为接收完了,你可以在发送的数据包报头里面加一些东西来判断这是第几个包,然后再判断有没有接收完
m0_37646670 2019-02-13
  • 打赏
  • 举报
回复
引用 4 楼 loveljy_19901114 的回复:
[quote=引用 2 楼 m0_37646670的回复:]比方说服务器发来100个包,我收完数据再检查少哪几个包
可现在 我是收到20个包 我就去检查了 然后又让服务器重发了80个包。。

你这个收到20个包就去检查这个动作是怎么触发的[/quote]

我有个队列用来存接受到的数据,然后在处理线程里处理一个包删除一个,
这个队列一边在加数据,一边在删除,我现在是当队列没数据了我就去检查收到的数据完整性

但似乎有时会处理完数据了 UDP包还没收到 导致进入检查数据确认重发包了
m0_37646670 2019-02-12
  • 打赏
  • 举报
回复
比方说服务器发来100个包,我收完数据再检查少哪几个包
可现在 我是收到20个包 我就去检查了 然后又让服务器重发了80个包。。
加载更多回复(1)

110,536

社区成员

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

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

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