i*****o 发帖数: 1714 | 1 害的我几个晚上没睡个好觉!
一直在用linux好久,时不时碰到个小问题,可从来没有到让人气愤的的地步,毕竟
linux好处多多,一点小问题就算了。可这次太让我忍无可忍,不得不上来骂几句。
话说偶在做一个voip的app,用linux做中转。linux上的code很简单,就是每20ms来个
50字节,从一个socket放到另外一个socket,这对偶做了n年网络工程师的人来说,小
菜一叠吧。可用这个app通话质量很差,偶抓破头皮看client的code,也没啥问题。用
sniffer看,原来每个packet间的间隔时大时小,导致很多packet不能按时到达,就过
期作废了。看sender的pattern,非常整齐。那就是linux的问题,偶就开始time自己的
code,同样的非常整齐,没有任何延迟。那是什么原因让linux不马上把偶的data传出
去,而看似毫无规律的乱传?
通过无数个google,bing,终于发现问题的根源。是linux作者在胡乱implement tcp
slow start. Slow start 的spec说tcp session can start with 3 max frame size
worth of data, 可linux这个人把它改为就是三个packets,不管有多少data。他这个
偷懒害了packet小而多类的应用,害的我熬了好几夜!
现在我也没什么气了,写出来说不定帮到碰到同样问题的同学。
★ 发自iPhone App: ChineseWeb 7.3 |
j*a 发帖数: 14423 | 2 pls do submit a patch. contribute back to community.
【在 i*****o 的大作中提到】 : 害的我几个晚上没睡个好觉! : 一直在用linux好久,时不时碰到个小问题,可从来没有到让人气愤的的地步,毕竟 : linux好处多多,一点小问题就算了。可这次太让我忍无可忍,不得不上来骂几句。 : 话说偶在做一个voip的app,用linux做中转。linux上的code很简单,就是每20ms来个 : 50字节,从一个socket放到另外一个socket,这对偶做了n年网络工程师的人来说,小 : 菜一叠吧。可用这个app通话质量很差,偶抓破头皮看client的code,也没啥问题。用 : sniffer看,原来每个packet间的间隔时大时小,导致很多packet不能按时到达,就过 : 期作废了。看sender的pattern,非常整齐。那就是linux的问题,偶就开始time自己的 : code,同样的非常整齐,没有任何延迟。那是什么原因让linux不马上把偶的data传出 : 去,而看似毫无规律的乱传?
|
l*****n 发帖数: 633 | 3 your voip app runs on tcp? why not udp?
【在 i*****o 的大作中提到】 : 害的我几个晚上没睡个好觉! : 一直在用linux好久,时不时碰到个小问题,可从来没有到让人气愤的的地步,毕竟 : linux好处多多,一点小问题就算了。可这次太让我忍无可忍,不得不上来骂几句。 : 话说偶在做一个voip的app,用linux做中转。linux上的code很简单,就是每20ms来个 : 50字节,从一个socket放到另外一个socket,这对偶做了n年网络工程师的人来说,小 : 菜一叠吧。可用这个app通话质量很差,偶抓破头皮看client的code,也没啥问题。用 : sniffer看,原来每个packet间的间隔时大时小,导致很多packet不能按时到达,就过 : 期作废了。看sender的pattern,非常整齐。那就是linux的问题,偶就开始time自己的 : code,同样的非常整齐,没有任何延迟。那是什么原因让linux不马上把偶的data传出 : 去,而看似毫无规律的乱传?
|
z**r 发帖数: 17771 | 4 second this
【在 l*****n 的大作中提到】 : your voip app runs on tcp? why not udp?
|
i*****o 发帖数: 1714 | 5 我想了很久为什么这个问题只有我碰到,google也没能帮多少忙,大概就是你说的,别
人都用udp。可我同样的code,如果对方不在,就voicemail存下来,不想丢frame。还
有我用http bypass firewall, 只有这样了。
★ 发自iPhone App: ChineseWeb 7.3
【在 l*****n 的大作中提到】 : your voip app runs on tcp? why not udp?
|
i*****o 发帖数: 1714 | 6 不用patch, config cwnd change就好了。
看到很多报道,所有大网站,google,msn,yahoo, init cwnd都从3改成10之类。
★ 发自iPhone App: ChineseWeb 7.3
【在 j*a 的大作中提到】 : pls do submit a patch. contribute back to community.
|
m**k 发帖数: 290 | 7 99% sure it's nothing to do with "wrong implementation" of TCP slow start.
you shouldn't use TCP at the first hand.
you need to know more about how a packet is transfered from a socket buffer
to driver and then to physical card. There are multiple buffers in this
process.
【在 i*****o 的大作中提到】 : 害的我几个晚上没睡个好觉! : 一直在用linux好久,时不时碰到个小问题,可从来没有到让人气愤的的地步,毕竟 : linux好处多多,一点小问题就算了。可这次太让我忍无可忍,不得不上来骂几句。 : 话说偶在做一个voip的app,用linux做中转。linux上的code很简单,就是每20ms来个 : 50字节,从一个socket放到另外一个socket,这对偶做了n年网络工程师的人来说,小 : 菜一叠吧。可用这个app通话质量很差,偶抓破头皮看client的code,也没啥问题。用 : sniffer看,原来每个packet间的间隔时大时小,导致很多packet不能按时到达,就过 : 期作废了。看sender的pattern,非常整齐。那就是linux的问题,偶就开始time自己的 : code,同样的非常整齐,没有任何延迟。那是什么原因让linux不马上把偶的data传出 : 去,而看似毫无规律的乱传?
|
j*a 发帖数: 14423 | 8 patch一下改成default吧,既然你说原作者误读了规范的文档
【在 i*****o 的大作中提到】 : 不用patch, config cwnd change就好了。 : 看到很多报道,所有大网站,google,msn,yahoo, init cwnd都从3改成10之类。 : : ★ 发自iPhone App: ChineseWeb 7.3
|
m********o 发帖数: 129 | 9 正解
【在 i*****o 的大作中提到】 : 不用patch, config cwnd change就好了。 : 看到很多报道,所有大网站,google,msn,yahoo, init cwnd都从3改成10之类。 : : ★ 发自iPhone App: ChineseWeb 7.3
|
i*****o 发帖数: 1714 | 10 这个要改可不是几行程序就能解决的。linux现在这方面有很多算法,每个都去测试就
累死了。这也是为甚么我在这个问题上花了很长时间。因为我直觉是tcp 哪个window的
问题,就去把每个算法的每个参数都拿来试,希望瞎猫碰死耗子,结果每个都不行,几
乎崩溃。
【在 j*a 的大作中提到】 : patch一下改成default吧,既然你说原作者误读了规范的文档
|
|
|
v*****r 发帖数: 1119 | 11 既然问题是packet间隔时大时小, set socket to use tcp_nodelay 试了吗?
【在 i*****o 的大作中提到】 : 害的我几个晚上没睡个好觉! : 一直在用linux好久,时不时碰到个小问题,可从来没有到让人气愤的的地步,毕竟 : linux好处多多,一点小问题就算了。可这次太让我忍无可忍,不得不上来骂几句。 : 话说偶在做一个voip的app,用linux做中转。linux上的code很简单,就是每20ms来个 : 50字节,从一个socket放到另外一个socket,这对偶做了n年网络工程师的人来说,小 : 菜一叠吧。可用这个app通话质量很差,偶抓破头皮看client的code,也没啥问题。用 : sniffer看,原来每个packet间的间隔时大时小,导致很多packet不能按时到达,就过 : 期作废了。看sender的pattern,非常整齐。那就是linux的问题,偶就开始time自己的 : code,同样的非常整齐,没有任何延迟。那是什么原因让linux不马上把偶的data传出 : 去,而看似毫无规律的乱传?
|
G*****h 发帖数: 33134 | 12 TCP 本来就不保证延迟
还是用 UDP 吧
【在 v*****r 的大作中提到】 : 既然问题是packet间隔时大时小, set socket to use tcp_nodelay 试了吗?
|
z**r 发帖数: 17771 | 13 UDP也不能。但是UDP开销小的多,对delay or jitter敏感的应用,无一例外都是用udp
。导致TCP延迟的因素太多了,这里面水很深很深,楼主说不是sender端,就是linux中
转出问题了,这个假设漏洞太多,基本不成立。
最关键的是,楼主的问题解决了吗?还是做了一番研究就放弃了?
这个tcp window不光和congestion window有关,也和advertised window有关,还有
ACK, retransmission等等。楼主要搞定这个问题了,欢迎给大家详细讲讲,俺发大包子
【在 G*****h 的大作中提到】 : TCP 本来就不保证延迟 : 还是用 UDP 吧
|
h*******t 发帖数: 2679 | 14 你的音频帧难道没有时间戳吗?时间戳当然是在发送端打。接收端存下来以后重新解码
,解码时时间戳就起作用了。
接收端接到数据后再打时间戳的话,鬼都不知道被延时成啥了。
【在 i*****o 的大作中提到】 : 害的我几个晚上没睡个好觉! : 一直在用linux好久,时不时碰到个小问题,可从来没有到让人气愤的的地步,毕竟 : linux好处多多,一点小问题就算了。可这次太让我忍无可忍,不得不上来骂几句。 : 话说偶在做一个voip的app,用linux做中转。linux上的code很简单,就是每20ms来个 : 50字节,从一个socket放到另外一个socket,这对偶做了n年网络工程师的人来说,小 : 菜一叠吧。可用这个app通话质量很差,偶抓破头皮看client的code,也没啥问题。用 : sniffer看,原来每个packet间的间隔时大时小,导致很多packet不能按时到达,就过 : 期作废了。看sender的pattern,非常整齐。那就是linux的问题,偶就开始time自己的 : code,同样的非常整齐,没有任何延迟。那是什么原因让linux不马上把偶的data传出 : 去,而看似毫无规律的乱传?
|
h*******t 发帖数: 2679 | 15 我觉得这个问题是视频音频工程师的活,不是网络工程师的活。
udp
包子
【在 z**r 的大作中提到】 : UDP也不能。但是UDP开销小的多,对delay or jitter敏感的应用,无一例外都是用udp : 。导致TCP延迟的因素太多了,这里面水很深很深,楼主说不是sender端,就是linux中 : 转出问题了,这个假设漏洞太多,基本不成立。 : 最关键的是,楼主的问题解决了吗?还是做了一番研究就放弃了? : 这个tcp window不光和congestion window有关,也和advertised window有关,还有 : ACK, retransmission等等。楼主要搞定这个问题了,欢迎给大家详细讲讲,俺发大包子
|
H*L 发帖数: 124 | 16 Your problem is probably due to bad interaction between tcp delayed ack and
nagle's algorithm. Nagle's algorithm won't send another packet until its
last in flight packet is acked, if the current pkt is too small; on the
other hand , at the other end, tcp will only send every other ack due to the
delayed ack policy
If all your packets are small it's almost guaranteed that you ll ran into
the situation where nagle's algorithm's end is waiting for its previous ack,
and the delayed ack end is not sending the ack but waiting for nagle's end
to send the next packet. The dead lock will result in a timeout which is
around 30ms in Linux, but could be up to 200ms in windows.
This is a common problem for apps with frequent small packets. The solution
is to disable either nagle's algorithm or delayed ack, both could be
achieved by set socket opt. |
i***c 发帖数: 301 | |
j**u 发帖数: 6059 | 18 谢谢经验
【在 i*****o 的大作中提到】 : 害的我几个晚上没睡个好觉! : 一直在用linux好久,时不时碰到个小问题,可从来没有到让人气愤的的地步,毕竟 : linux好处多多,一点小问题就算了。可这次太让我忍无可忍,不得不上来骂几句。 : 话说偶在做一个voip的app,用linux做中转。linux上的code很简单,就是每20ms来个 : 50字节,从一个socket放到另外一个socket,这对偶做了n年网络工程师的人来说,小 : 菜一叠吧。可用这个app通话质量很差,偶抓破头皮看client的code,也没啥问题。用 : sniffer看,原来每个packet间的间隔时大时小,导致很多packet不能按时到达,就过 : 期作废了。看sender的pattern,非常整齐。那就是linux的问题,偶就开始time自己的 : code,同样的非常整齐,没有任何延迟。那是什么原因让linux不马上把偶的data传出 : 去,而看似毫无规律的乱传?
|
i*****o 发帖数: 1714 | 19 这个问题已经解决了, 就是改一下ip route default initcwnd, default是3,我改
成20就好了。
关于这个问题的根源我已经说过, 就是linux上对tcp slow start的实现没有按通常的
要求去做。tcp slow start是为了避免congestion,省的一个新的session来了以后,
一下子传太多造成没有必要的drop frame和retransmission。公认的实现是start with
3x mss。就是说ethernet上可以一下子送1500*3 = 4500字节。4500字节对我来说就
是90个voice packet(差不多两秒的通话)足够用的了。可linux上写这个程序的人偷
懒,把slow start定义为start with 3 packets,不管这个packet里有多少字节。这样
我的应用就被卡注了。想想3g network round trip delay差不多在60ms-200ms之间,
200ms就是10个voice packet,可linux只给3个packet,所以就不断的drop frame(
voice frame 过期作废)。
可气的是这个问题很隐蔽,以前所有的问题都可以google解决,这个我google, bing
都用了,就是没答案。给我的提示就是去试不同的算法。linux上slow start竟然有三
四种算法,害得我一个一个地试,都不行。现在想想为什么有这么多的算法,是不是因
为大家在做测试的时候不满意,就开始改算法,而忽略了最基本的底层假设不成立呢?
其它的问题:
tcp_no_delay一开始就enable了,delayed ack也不是问题,receive window够大。
至于用udp还是tcp这是应用决定的,tcp对我来说更好。
udp
包子
【在 z**r 的大作中提到】 : UDP也不能。但是UDP开销小的多,对delay or jitter敏感的应用,无一例外都是用udp : 。导致TCP延迟的因素太多了,这里面水很深很深,楼主说不是sender端,就是linux中 : 转出问题了,这个假设漏洞太多,基本不成立。 : 最关键的是,楼主的问题解决了吗?还是做了一番研究就放弃了? : 这个tcp window不光和congestion window有关,也和advertised window有关,还有 : ACK, retransmission等等。楼主要搞定这个问题了,欢迎给大家详细讲讲,俺发大包子
|
r****y 发帖数: 26819 | 20 那freebsd之类的其它系统是不是也跟linux一样?
with
【在 i*****o 的大作中提到】 : 这个问题已经解决了, 就是改一下ip route default initcwnd, default是3,我改 : 成20就好了。 : 关于这个问题的根源我已经说过, 就是linux上对tcp slow start的实现没有按通常的 : 要求去做。tcp slow start是为了避免congestion,省的一个新的session来了以后, : 一下子传太多造成没有必要的drop frame和retransmission。公认的实现是start with : 3x mss。就是说ethernet上可以一下子送1500*3 = 4500字节。4500字节对我来说就 : 是90个voice packet(差不多两秒的通话)足够用的了。可linux上写这个程序的人偷 : 懒,把slow start定义为start with 3 packets,不管这个packet里有多少字节。这样 : 我的应用就被卡注了。想想3g network round trip delay差不多在60ms-200ms之间, : 200ms就是10个voice packet,可linux只给3个packet,所以就不断的drop frame(
|
|
|
c*****e 发帖数: 3226 | 21 why do not you use open source rtp stack?
你这么写完全是闭门造车。
【在 i*****o 的大作中提到】 : 害的我几个晚上没睡个好觉! : 一直在用linux好久,时不时碰到个小问题,可从来没有到让人气愤的的地步,毕竟 : linux好处多多,一点小问题就算了。可这次太让我忍无可忍,不得不上来骂几句。 : 话说偶在做一个voip的app,用linux做中转。linux上的code很简单,就是每20ms来个 : 50字节,从一个socket放到另外一个socket,这对偶做了n年网络工程师的人来说,小 : 菜一叠吧。可用这个app通话质量很差,偶抓破头皮看client的code,也没啥问题。用 : sniffer看,原来每个packet间的间隔时大时小,导致很多packet不能按时到达,就过 : 期作废了。看sender的pattern,非常整齐。那就是linux的问题,偶就开始time自己的 : code,同样的非常整齐,没有任何延迟。那是什么原因让linux不马上把偶的data传出 : 去,而看似毫无规律的乱传?
|
c*****e 发帖数: 3226 | 22 opensips 只有signal, 没rtp.
【在 i***c 的大作中提到】 : 何必自己造轮子,高个opensips很好用的
|
N*****m 发帖数: 42603 | 23 同意
可见良好的科研习惯是多么重要
【在 c*****e 的大作中提到】 : why do not you use open source rtp stack? : 你这么写完全是闭门造车。
|
a9 发帖数: 21638 | 24 有mediaproxy啊。
【在 c*****e 的大作中提到】 : opensips 只有signal, 没rtp.
|
N******K 发帖数: 10202 | 25 open source rtp stack 包括了tcp协议? 把linux里面的就给屏蔽了?
【在 c*****e 的大作中提到】 : why do not you use open source rtp stack? : 你这么写完全是闭门造车。
|
l**n 发帖数: 7272 | 26 Does this problem exist in Windows or other platform (Android/ iOS)?
with
【在 i*****o 的大作中提到】 : 这个问题已经解决了, 就是改一下ip route default initcwnd, default是3,我改 : 成20就好了。 : 关于这个问题的根源我已经说过, 就是linux上对tcp slow start的实现没有按通常的 : 要求去做。tcp slow start是为了避免congestion,省的一个新的session来了以后, : 一下子传太多造成没有必要的drop frame和retransmission。公认的实现是start with : 3x mss。就是说ethernet上可以一下子送1500*3 = 4500字节。4500字节对我来说就 : 是90个voice packet(差不多两秒的通话)足够用的了。可linux上写这个程序的人偷 : 懒,把slow start定义为start with 3 packets,不管这个packet里有多少字节。这样 : 我的应用就被卡注了。想想3g network round trip delay差不多在60ms-200ms之间, : 200ms就是10个voice packet,可linux只给3个packet,所以就不断的drop frame(
|
N*n 发帖数: 456 | 27 re..
with
【在 i*****o 的大作中提到】 : 这个问题已经解决了, 就是改一下ip route default initcwnd, default是3,我改 : 成20就好了。 : 关于这个问题的根源我已经说过, 就是linux上对tcp slow start的实现没有按通常的 : 要求去做。tcp slow start是为了避免congestion,省的一个新的session来了以后, : 一下子传太多造成没有必要的drop frame和retransmission。公认的实现是start with : 3x mss。就是说ethernet上可以一下子送1500*3 = 4500字节。4500字节对我来说就 : 是90个voice packet(差不多两秒的通话)足够用的了。可linux上写这个程序的人偷 : 懒,把slow start定义为start with 3 packets,不管这个packet里有多少字节。这样 : 我的应用就被卡注了。想想3g network round trip delay差不多在60ms-200ms之间, : 200ms就是10个voice packet,可linux只给3个packet,所以就不断的drop frame(
|