免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: csumck
打印 上一主题 下一主题

[C++] 大的数据包是不是拆成小于MTU的多个小包发送会好些? [复制链接]

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
11 [报告]
发表于 2014-07-11 13:50 |只看该作者
TCP自己管分包确实就是瞎操心,UDP倒是有必要的,这跟其实现机制有关。
TCP不管你怎么分包,最终实际上怎么分还是底层说了算,除非像楼上说的发个包sleep一下,不过TCP真要这么做那就要笑掉大牙了。
UDP则有所不同,如果一次发一个大包,当然它也会被底层按MTU拆成多个小包,发到对端,如果有一个小包没有收到,那么这个大包就废了,在网络状况不乐观的情况下,很可能经常丢小包,而一旦一个小包丢掉就废了一个大包,所以就容易出现经常收不到包的状况,即使重发大包也未必能及时解决问题(假设大包分成20个小包,重发的情况下,可能这次丢3号,下次丢7号,未必能一次20个小包都不丢);而如果自己拆成小包,虽然也可能会丢小包,但小包之间不会相互影响,其它的小包可以收到,假设业务逻辑上这些小包可以干活那么直接干活去就行了,即使不能干活,需要等丢了的包发过来,那么多次重发小包也总会有一次可以到达。

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
12 [报告]
发表于 2014-07-11 13:54 |只看该作者
其实LZ说的这个TCP现象,九成是自己代码写得有问题。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
13 [报告]
发表于 2014-07-11 14:21 |只看该作者
w_anthony 发表于 2014-07-11 13:54
其实LZ说的这个TCP现象,九成是自己代码写得有问题。


我们软件有个拉文件的协议, TCP的, 几百K, 客户端每次请求其中的一片, 服务端把这一片的数据回给客户端, 这样分好多次拉完.
我们的客户端同事用抓包工具观察过, 我们在windows上用wireshark抓包, 数据片大的时候(比如10K一个包)TCP出现重传的机会大很多, 一旦重传, 后面很多数据包都卡住了, 连我们协议里的心跳包都卡住了.
但是换成1.3K的包之后极少出现重传了, 不过这样来回的请求应答次数是增多了.

所以我觉着不是代码问题, tcp重传是确实存在的, 这不是我应用程序能够造成的.  而且网络情况很好的机房即使10K一个包也很少重传.

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
14 [报告]
发表于 2014-07-11 14:41 |只看该作者
抓包工具看到TCP重传这有什么奇怪的,这不是正常现象吗?如果代码写得没有问题,我敢说你一次send比分多次send的总耗时只会少不会多(即小于等于)。
而且貌似你的心跳机制也有问题,既然有数据待发送,那么根本不需要心跳包(发送缓冲区有数据还要心跳有什么用,心跳是为了维护没数据时候的连接状态,应该做一个判断),对端也是一样,既然一直有收到数据,就不需要依赖心跳机制来判断对方是否还连接着。
还有什么叫后面的数据包卡住了?我不知道你的代码流程是什么样的,听起来难道是你的一端向对端发送数据,必须等到对端响应发回一个“表示自己已收到”的数据包,才会继续发送下一段吗?如果是这样的话,你的TCP做得也真是太非主流了,完全没发挥TCP应有的性能。如果不需要对端响应,都是直接发送,那么不管怎样分片,实际上并没有什么区别,除非在传文件的时候,还有其它业务逻辑需要并行处理,这样的话应该另外开一个连接专门传输文件数据为好。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
15 [报告]
发表于 2014-07-11 15:13 |只看该作者
w_anthony 发表于 2014-07-11 14:41
抓包工具看到TCP重传这有什么奇怪的,这不是正常现象吗?如果代码写得没有问题,我敢说你一次send比分多次s ...


抓包工具看到TCP重传这有什么奇怪的,这不是正常现象吗?如果代码写得没有问题,我敢说你一次send比分多次send的总耗时只会少不会多(即小于等于)。
    没错, 分多次send的消耗肯定会大.
而且貌似你的心跳机制也有问题,既然有数据待发送,那么根本不需要心跳包(发送缓冲区有数据还要心跳有什么用,心跳是为了维护没数据时候的连接状态,应该做一个判断),对端也是一样,既然一直有收到数据,就不需要依赖心跳机制来判断对方是否还连接着。
    这个心跳确实有点多余, 但是不会有多少数据量, 所以这样实现问题也不大吧
还有什么叫后面的数据包卡住了?我不知道你的代码流程是什么样的,听起来难道是你的一端向对端发送数据,必须等到对端响应发回一个“表示自己已收到”的数据包,才会继续发送下一段吗?如果是这样的话,你的TCP做得也真是太非主流了,完全没发挥TCP应有的性能。如果不需要对端响应,都是直接发送,那么不管怎样分片,实际上并没有什么区别,除非在传文件的时候,还有其它业务逻辑需要并行处理,这样的话应该另外开一个连接专门传输文件数据为好。
    "后面的数据包卡住", 我的意思是说, 比如服务端send了10个包, 第三个包发生重传了, 在这个包能被客户端应用程序正常接收到之前,第4到第10个包都不会被客户端的应用程序收到, 这时客户端的表现就好像数据卡住了. 那个包不停的重传, 最后连心跳都超时了.  现在我们传文件确实也是新开了连接, 现在的问题就是这条连接不太稳定, 观察到的现象就是包发送的小一点, 重传会少很多, 就不会出现数据卡住的情况.  我发这个贴就是想跟大家请教下这个问题的解决方法.

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
16 [报告]
发表于 2014-07-11 15:19 |只看该作者
回复 15# csumck
“听起来难道是你的一端向对端发送数据,必须等到对端响应发回一个“表示自己已收到”的数据包,才会继续发送下一段吗?”
你的代码到底没有这个机制?

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
17 [报告]
发表于 2014-07-11 15:24 |只看该作者
你的这个“一直重传的描述”,让我想到一点,是否是对端没有在接收数据?比如对端recv一次100k,但是实际上只接收了50k,还有50k没有接收,但是你没有判断返回值也没有继续recv,或者有判断返回值但是再次接收的事件没有触发导致没有机会去recv剩余的数据。这样发送端的因为没有接受到对端协议层的已接收的控制包,因而滑动窗口下不去,所以就卡住了。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
18 [报告]
发表于 2014-07-11 15:33 |只看该作者
w_anthony 发表于 2014-07-11 15:19
回复 15# csumck
“听起来难道是你的一端向对端发送数据,必须等到对端响应发回一个“表示自己已收到”的 ...


我们这个是客户端发起的拉取请求, 客户端收到一个文件片段后, 会请求下一片.  这个"请求下一片"跟你说的"表示自己收到"我觉得是差不多的逻辑.

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
19 [报告]
发表于 2014-07-11 15:38 |只看该作者
w_anthony 发表于 2014-07-11 15:24
你的这个“一直重传的描述”,让我想到一点,是否是对端没有在接收数据?比如对端recv一次100k,但是实际上 ...


不是这个, 这里确认窗口是足够的, 就是不停的重传, 一直不能把丢掉的包补上, 所以卡住了.

你说的这个问题, 我们客户端确实曾经出现过, 当时客户端有个bug导致可读事件永远不会触发, 然后抓包就看到窗口逐渐变小, 最后满了就发不出去了. 那个bug后来被修复了, 而且修复后客户端把tcp接收缓存开到几M了, 很难满掉.

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
20 [报告]
发表于 2014-07-11 15:39 |只看该作者
回复 18# csumck


    我觉得很可能是接收端的代码写得有问题,很可能是有数据可接收的时候,却没有去接收,导致发送端的滑动窗口下不去就卡住了。
你简单地可以发下接收端的代码大致看看……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP