大数据 UDP接收问题

vbcrack 2014-02-13 03:10:32
在windows xp下采用socket开发一程序接收UDP数据,接收速度为800Mbps,开始工作的一段时间(几十分钟到几小时不等)收数正常,一段时间后,接收速度变慢,大部分UDP数据包接收不到,但用抓包工具可以抓到socket未收到的UDP包,分析抓到的UDP包未找到异常;重新启动程序接收速度还是很慢,只有在重新启动系统或重启网卡后socket程序接收数据才能正常,请教您有遇到类似问题吗?有什么建议,谢谢!
...全文
1840 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
worldy 2014-03-23
  • 打赏
  • 举报
回复
引用 29 楼 vbcrack 的回复:
经过今天的测试,未发现有内存泄露; 局网为全千兆网络; 接收缓冲区设置为4*1024*1024,应该够了吧;
没有泄漏不等于及时释放,累计内存一直增加,但在退出的时候清理干净也不会泄漏内存
worldy 2014-03-23
  • 打赏
  • 举报
回复
应该是内存资源没有及时释放,造成了虚拟内存交换数据,所以速度变慢
  • 打赏
  • 举报
回复
不错的问题 mark一下 楼主找出问题的话记得说一下是哪出的问题
vbcrack 2014-03-04
  • 打赏
  • 举报
回复
经过今天的测试,未发现有内存泄露; 局网为全千兆网络; 接收缓冲区设置为4*1024*1024,应该够了吧;
csuestc 2014-02-28
  • 打赏
  • 举报
回复
嗯 不错很有意义的测试,在一般多台机局域网中一般负载超过30%就会有以太网的冲突了,会降低网络性能;不知道楼主的带宽有多少?
汗晕倒 2014-02-26
  • 打赏
  • 举报
回复
接收速度是否没有发送的快,这样会让网络中的包越来越多,这个有没有测试,当接收慢的时候,检测接收端的的接收过程是否还正常,接收buf空间是否还能满足接收要求。
vbcrack 2014-02-25
  • 打赏
  • 举报
回复
硬件暂时无法更改,只能发送标准的UDP数据; 现在只能尽量完善和优化接收端,只要接收端能稳定收到数据即可,偶尔掉几包是允许的,只要不在工作一段时间后丢包很严重或收不到UDP包即可
vbcrack 2014-02-25
  • 打赏
  • 举报
回复
引用 22 楼 danscort2000 的回复:
[quote=引用 21 楼 vbcrack 的回复:] 谢谢各位指导!!! 发送端是由硬件完成,没有办法提供可靠传输,现在只能在接收端想办法。 程序内存是否存在泄漏还在排查,接收端的接收缓冲已经改成了4*1024*1024。 请教下,有没有办法清理socket接收端的缓冲,避免接收缓冲溢出?
给你个大规模并发处理的思路 首先分配2块以上全局缓冲内存,要足够大 开一个线程专门使用recvfrom 接收数据包 一块缓冲放满了就切换到另一块继续,注意这个线程不要进行逻辑判断什么的 只进行接收和写数据 另外开1个或者几个线程专门执行数据逻辑的处理 就是从你预先分配的全局缓冲内存中读数据 至于怎么同步 怎么并行处理,你应该能解决好的 重点在于 2块以上的内存缓冲 必须预先分配好,不要使用虚拟分配,虚拟分配会导致开始时性能卡壳 其次就是接收和数据处理线程严格分开,有必要的话,可以为recvfrom所在线程的优先级调高 1 做到这两条,结合我上面给出的优化,因为缓冲导致的丢包率应该会比你的实现低,当然代价是CPU资源开销会比你原来的实现高 [/quote] 感谢,我先您提供的思路试试看。
UDX协议 2014-02-25
  • 打赏
  • 举报
回复
如果硬件可编程的话,可以移入可靠UDP传输算法,比如UDX,UDT协议,包括其他的enet等。 如果硬件不能值入程序的话,基本上不可能完成可靠。 接收方再做努力也不是行的。 间接方法是,在硬件所在网络环境,局域网或是本机内,接收UDP包,然后通过可靠协议转发给你的客户端,由于是本机转发,所以,丢包,延迟可以忽略。同样可以达到你想要的目的。 并发,是要看编程实现者的经验,不管是哪种模型,IOCP,EPOLL,用多线程一样可以实现很高效的并发,这个要看人。
就想叫yoko 2014-02-25
  • 打赏
  • 举报
回复
引用 21 楼 vbcrack 的回复:
谢谢各位指导!!! 发送端是由硬件完成,没有办法提供可靠传输,现在只能在接收端想办法。 程序内存是否存在泄漏还在排查,接收端的接收缓冲已经改成了4*1024*1024。 请教下,有没有办法清理socket接收端的缓冲,避免接收缓冲溢出?
硬件完成不能编写上层协议代码吗 丢包了可以不管,不需要重传?
danscort2000 2014-02-25
  • 打赏
  • 举报
回复
引用 21 楼 vbcrack 的回复:
谢谢各位指导!!! 发送端是由硬件完成,没有办法提供可靠传输,现在只能在接收端想办法。 程序内存是否存在泄漏还在排查,接收端的接收缓冲已经改成了4*1024*1024。 请教下,有没有办法清理socket接收端的缓冲,避免接收缓冲溢出?
给你个大规模并发处理的思路 首先分配2块以上全局缓冲内存,要足够大 开一个线程专门使用recvfrom 接收数据包 一块缓冲放满了就切换到另一块继续,注意这个线程不要进行逻辑判断什么的 只进行接收和写数据 另外开1个或者几个线程专门执行数据逻辑的处理 就是从你预先分配的全局缓冲内存中读数据 至于怎么同步 怎么并行处理,你应该能解决好的 重点在于 2块以上的内存缓冲 必须预先分配好,不要使用虚拟分配,虚拟分配会导致开始时性能卡壳 其次就是接收和数据处理线程严格分开,有必要的话,可以为recvfrom所在线程的优先级调高 1 做到这两条,结合我上面给出的优化,因为缓冲导致的丢包率应该会比你的实现低,当然代价是CPU资源开销会比你原来的实现高
vbcrack 2014-02-25
  • 打赏
  • 举报
回复
谢谢各位指导!!! 发送端是由硬件完成,没有办法提供可靠传输,现在只能在接收端想办法。 程序内存是否存在泄漏还在排查,接收端的接收缓冲已经改成了4*1024*1024。 请教下,有没有办法清理socket接收端的缓冲,避免接收缓冲溢出?
zdleek 2014-02-20
  • 打赏
  • 举报
回复
楼主如果可以确定自己程序不存在内存泄露等问题,那么参考17楼的是很好的方法
zdleek 2014-02-20
  • 打赏
  • 举报
回复
引用 17 楼 danscort2000 的回复:
你只是单纯使用recvfrom进行的包接收测试吧? 没有对UDP加入自己的可靠传输模式, 如果是这样的话应该是正常的,udp本身就是不可靠,乱序的 首先 sendto 发送端,当socket发送缓冲占满,会有阶段性丢包出现 其次 recvfrom 接收端 当socket接收缓冲满,由于TCP/IP协议栈是运行在内核态,因此你的recvfrom并不会在用户态被立即调用,而且由于TCP/IP协议栈的内部锁的存在,这个时候是线性执行,而不是并发执行,那么后续包会被丢弃,也就是出现你说的 抓包可以抓到,但是你的程序接收不到的现象,因为用户太无法及时响应,导致内核态的缓冲长时间处于高负载状态,结局就是,随着时间的推移丢包越来越多。 你如果只想简单的临时化解,可以采用的方法是 [1] 增加接收端socket的接收缓冲大小例如到 5*1024*1024, set socket opl [2] 检测发送端sendto 的返回值,当出现SOCKET——ERROR,使用select 等SOCKET缓冲被清除 使用这两步操作,在1000Mbps环境下,只要你的CPU够强,处理逻辑够简单,一般就没有什么大问题 终极解决还是要自己编写可靠UDP传输,可以参考开源的例如 udt , 或者 http://enet.bespin.org/ 这些都是很不错的简单UDP可靠传输的实现
很强,学习了
brk1985 2014-02-20
  • 打赏
  • 举报
回复
引用 17 楼 danscort2000 的回复:
你只是单纯使用recvfrom进行的包接收测试吧? 没有对UDP加入自己的可靠传输模式, 如果是这样的话应该是正常的,udp本身就是不可靠,乱序的 首先 sendto 发送端,当socket发送缓冲占满,会有阶段性丢包出现 其次 recvfrom 接收端 当socket接收缓冲满,由于TCP/IP协议栈是运行在内核态,因此你的recvfrom并不会在用户态被立即调用,而且由于TCP/IP协议栈的内部锁的存在,这个时候是线性执行,而不是并发执行,那么后续包会被丢弃,也就是出现你说的 抓包可以抓到,但是你的程序接收不到的现象,因为用户太无法及时响应,导致内核态的缓冲长时间处于高负载状态,结局就是,随着时间的推移丢包越来越多。 你如果只想简单的临时化解,可以采用的方法是 [1] 增加接收端socket的接收缓冲大小例如到 5*1024*1024, set socket opl [2] 检测发送端sendto 的返回值,当出现SOCKET——ERROR,使用select 等SOCKET缓冲被清除 使用这两步操作,在1000Mbps环境下,只要你的CPU够强,处理逻辑够简单,一般就没有什么大问题 终极解决还是要自己编写可靠UDP传输,可以参考开源的例如 udt , 或者 http://enet.bespin.org/ 这些都是很不错的简单UDP可靠传输的实现
mark下。。。
danscort2000 2014-02-20
  • 打赏
  • 举报
回复
你只是单纯使用recvfrom进行的包接收测试吧? 没有对UDP加入自己的可靠传输模式, 如果是这样的话应该是正常的,udp本身就是不可靠,乱序的 首先 sendto 发送端,当socket发送缓冲占满,会有阶段性丢包出现 其次 recvfrom 接收端 当socket接收缓冲满,由于TCP/IP协议栈是运行在内核态,因此你的recvfrom并不会在用户态被立即调用,而且由于TCP/IP协议栈的内部锁的存在,这个时候是线性执行,而不是并发执行,那么后续包会被丢弃,也就是出现你说的 抓包可以抓到,但是你的程序接收不到的现象,因为用户太无法及时响应,导致内核态的缓冲长时间处于高负载状态,结局就是,随着时间的推移丢包越来越多。 你如果只想简单的临时化解,可以采用的方法是 [1] 增加接收端socket的接收缓冲大小例如到 5*1024*1024, set socket opl [2] 检测发送端sendto 的返回值,当出现SOCKET——ERROR,使用select 等SOCKET缓冲被清除 使用这两步操作,在1000Mbps环境下,只要你的CPU够强,处理逻辑够简单,一般就没有什么大问题 终极解决还是要自己编写可靠UDP传输,可以参考开源的例如 udt , 或者 http://enet.bespin.org/ 这些都是很不错的简单UDP可靠传输的实现
UDX协议 2014-02-20
  • 打赏
  • 举报
回复
这应该是你资源有泄露的原因,只要掌握的好,应该不成问题,我的程序已经帮你验证了,是你的程序代码问题
大道曙光 2014-02-19
  • 打赏
  • 举报
回复
前排学习。
vbcrack 2014-02-19
  • 打赏
  • 举报
回复
引用 13 楼 VisualEleven 的回复:
你接收端的代码是怎么写的,一个单独的线程,循环recvfrom()?
是的,采用的是socket接收
Eleven 2014-02-19
  • 打赏
  • 举报
回复
你接收端的代码是怎么写的,一个单独的线程,循环recvfrom()?
加载更多回复(12)

18,355

社区成员

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

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