udp传输到底会不会发生粘包问题

D_Future 2013-08-13 03:16:27
看了一些解答说udp都是整包发,整包收,不会发生粘包,但是周围的前辈们说还是有可能的,我们现在服务端收到的数据也就几十个字节的大小,收的频率是每秒10条左右吧,到底会不会发生粘包现象,就是两条数据粘一块,或者其中一条数据不完整另一个完整

下面这个是具体代码,第一个是定义数据包的,第二个是判断粘包的

现在程序应该怎么优化?
1.既然粘包概率极低,可不可以直接判断包的大小,过大直接把这包甩了不要?
2.还是对下面的粘包算法进行优化?

给个思路吧 ,感谢各位!!

#define PACKAGE_LEN 1024
typedef struct _Package
{
char chData[PACKAGE_LEN];
int nLen;
SOCKADDR_IN addr;
}Package;

	
int nAnalysed = 0;
do
{
nAnalysed = m_DataAnalysis.AnalyseDevice( pack.chData, pack.addr );

pack.nLen -= nAnalysed;
if( pack.nLen > 0 )
{
::memmove( pack.chData, pack.chData + nAnalysed, PACKAGE_LEN - nAnalysed );
}
else if( pack.nLen < 0 )
{
TRACE(_T("\n处理设备的数据比收到的数据多!"));
}
}while( pack.nLen > 0 );
...全文
4946 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
Mr.Brain 2015-06-11
  • 打赏
  • 举报
回复
引用 22 楼 irplay 的回复:
哈哈哈哈,好搞笑...udp包 貌似会乱序.先发的可能后到噢.
乱序应该不要紧吧,就算乱序,在承受范围内重新排序也可以啊
Mr.Brain 2015-06-11
  • 打赏
  • 举报
回复
谢谢前辈们,学习了!
cc___999 2015-05-06
  • 打赏
  • 举报
回复
学习了!!!
craigtao 2014-07-17
  • 打赏
  • 举报
回复
晚辈受教了,长知识了,谢谢各位前辈的分享讨论,实在是感谢, 最近也是做这方面,设备端向服务器发送文件,UDP方式, 现在没有好的思路, 现在自己想了一套不知道合理不合理的方法,说出来,前辈们指导一下, 文件主要是图片文件和视频文件 设备端把文件分包发送,每个包512字节,都有序号,服务器端收到以后记录一个表, 设备端先发送文件信息,然后再发送文件内容, 整个包结束后(根据序号和总包数),服务器端查看表格那个包没有到达或者校验失败的, 请求设备重新发送, 不知道晚辈这个方法行不行,设备端主要有个问题是,使用的是2G网络,发送的数据量小,而且 可能发送的过程中会没有信号,
hping1016 2014-05-04
  • 打赏
  • 举报
回复
分析得不错,支持
九品仙 2014-04-23
  • 打赏
  • 举报
回复
哈哈哈哈,好搞笑...udp包 貌似会乱序.先发的可能后到噢.
youngwolf 2013-08-15
  • 打赏
  • 举报
回复
这些人是什么前辈?
木头菇 2013-08-14
  • 打赏
  • 举报
回复
引用 16 楼 woshinia 的回复:
[quote=引用 15 楼 spirit008 的回复:] [quote=引用 14 楼 woshinia 的回复:] UDP有明确的结束标志,不会有粘包的,UDP本身有对数据完整性的校验,不完整的包会被丢弃,所以也不会不完整。如果你是指一次会受到2-3个UDP包,那只要根据开头和结束标记分割就行了。TCP的话,只要所需数据块的大小是确定的,然后每次接受的数据根据长度,不足就继续收,超过就把剩余的存下来与下次的接受合并,就可以解决粘包问题。
从哪里看来的一次能收2-3个udp包的。[/quote] 这个用udp协议接收估计每次只会收到1个,但如果是原始套接字的话,就可能收到多个。[/quote] datagram socket 层面不管一次recv,还是一次event,一次就一个包。 网卡层面不考虑,那是靠边界分割的。操作系统给我们做好了,不必要再造轮子。 另考虑如果你调用recv的buffer传小了,那么剩余的数据怎么办,答案msdn也给出了。 If the datagram or message is larger than the buffer specified, the buffer is filled with the first part of the datagram, and recv generates the error WSAEMSGSIZE. For unreliable protocols (for example, UDP) the excess data is lost; for reliable protocols, the data is retained by the service provider until it is successfully read by calling recv with a large enough buffer.
woshinia 2013-08-14
  • 打赏
  • 举报
回复
引用 15 楼 spirit008 的回复:
[quote=引用 14 楼 woshinia 的回复:] UDP有明确的结束标志,不会有粘包的,UDP本身有对数据完整性的校验,不完整的包会被丢弃,所以也不会不完整。如果你是指一次会受到2-3个UDP包,那只要根据开头和结束标记分割就行了。TCP的话,只要所需数据块的大小是确定的,然后每次接受的数据根据长度,不足就继续收,超过就把剩余的存下来与下次的接受合并,就可以解决粘包问题。
从哪里看来的一次能收2-3个udp包的。[/quote] 这个用udp协议接收估计每次只会收到1个,但如果是原始套接字的话,就可能收到多个。
木头菇 2013-08-14
  • 打赏
  • 举报
回复
引用 14 楼 woshinia 的回复:
UDP有明确的结束标志,不会有粘包的,UDP本身有对数据完整性的校验,不完整的包会被丢弃,所以也不会不完整。如果你是指一次会受到2-3个UDP包,那只要根据开头和结束标记分割就行了。TCP的话,只要所需数据块的大小是确定的,然后每次接受的数据根据长度,不足就继续收,超过就把剩余的存下来与下次的接受合并,就可以解决粘包问题。
从哪里看来的一次能收2-3个udp包的。
woshinia 2013-08-14
  • 打赏
  • 举报
回复
UDP有明确的结束标志,不会有粘包的,UDP本身有对数据完整性的校验,不完整的包会被丢弃,所以也不会不完整。如果你是指一次会受到2-3个UDP包,那只要根据开头和结束标记分割就行了。TCP的话,只要所需数据块的大小是确定的,然后每次接受的数据根据长度,不足就继续收,超过就把剩余的存下来与下次的接受合并,就可以解决粘包问题。
小雨好赖床 2013-08-14
  • 打赏
  • 举报
回复
追加:
一般网络编程时候,也会定义数据包头,包体
TCP接收数据的时候,可以先接收包头进行安全验证,通过继续接受包体,不通过直接断开连接
UDP接受则没有办法这样做,你再大的一个数据,一个RECV,也是直接接受,不能说我先接受多长,这样是不可能的(不过一般大文件数据,都不会用UDP这种不安全传输)
小雨好赖床 2013-08-14
  • 打赏
  • 举报
回复 3
从TCP与UDP的区别讲起
网络数据经过路由器,如果数据很小,没有超过路由器的封包大小,就会直接直接经过路由器到达下一个路由器,一层一层最终到达目的地
如果数据很大,这里指一个发送,超过了路由器的封包大小,那么路由器就会把这个数据包进行拆分,比如拆分成A B C三个包,这三个包都没有超过路由器的封包大小,到达下一个路由器的时候,TCP与UDP的区别就来了:
TCP收到A的时候,会resp通知源路由器,A到达,B C包依然如此,如果由于网络的各种原因,目的路由收到了A C,B没有收到,TCP会要求源路由把B包重新发一次,直到ABC包目的路由都接受到了,那么目的路由把ABC包重新组成起始包,继续往下一个路由发送,这就是TCP安全连接的由来,只要发送,我就能保证目的一定能收到(网络断开能检测到)
UDP则不是这样,如果ABC包拆分之后,目的路由只收到AC,经过检测,B没有被收到,那么此包就会被当作不完整,直接被丢弃。由于UDP没有resp的通知过程,所以,UDP的传输效率要高一些,当然安全性也低一些
由上面的这些可以得出结论:UDP是绝对不会被粘包,因为路由器收到的只会是完整数据才会继续下发,什么粘包处理完全没有必要
jiayou0909 2013-08-14
  • 打赏
  • 举报
回复
引用 10 楼 spirit008 的回复:
[quote=引用 8 楼 u011560888 的回复:] 从tcp-ip驱动程序的角度看,#6楼是对的。 但是如果是调用socket函数编程,你的前辈就是对的。
哪层也不对,你试试就知道了[/quote]
引用 10 楼 spirit008 的回复:
[quote=引用 8 楼 u011560888 的回复:] 从tcp-ip驱动程序的角度看,#6楼是对的。 但是如果是调用socket函数编程,你的前辈就是对的。
哪层也不对,你试试就知道了[/quote] 不必试了。我想很难试出粘包问题。只是以防万一。
木头菇 2013-08-14
  • 打赏
  • 举报
回复
引用 8 楼 u011560888 的回复:
从tcp-ip驱动程序的角度看,#6楼是对的。 但是如果是调用socket函数编程,你的前辈就是对的。
哪层也不对,你试试就知道了
傻X 2013-08-14
  • 打赏
  • 举报
回复
引用 3 楼 u011371217 的回复:
[quote=引用 1 楼 ouyh12345 的回复:] 数据不完整是可能的,可以通过工具限制带宽来验证
为什么会出现不完整的包? 丢包还能丢一半么? 还有限制带宽工具,怎么弄。。。。[/quote] UDP本身没有保证正确性的重发机制。如果繁忙起来丢包是无比正常的。丢包应该是丢一整个Send
jiayou0909 2013-08-14
  • 打赏
  • 举报
回复
从tcp-ip驱动程序的角度看,#6楼是对的。 但是如果是调用socket函数编程,你的前辈就是对的。
D_Future 2013-08-14
  • 打赏
  • 举报
回复
引用 6 楼 spirit008 的回复:
udp要么收的是完整包,要么丢,你们这是什么前辈
以前的代码中带这个粘包处理功能,但是因为加了这个处理十分耗时,所以想直接删掉,但是前辈们说还最好不要删,能修改算法是最好的
木头菇 2013-08-14
  • 打赏
  • 举报
回复
udp要么收的是完整包,要么丢,你们这是什么前辈
Eleven 2013-08-14
  • 打赏
  • 举报
回复
UDP不是流协议,有消息边界,不存在粘包的问题。要丢就是整个包都丢了。
加载更多回复(7)

18,358

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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