什么情况下tcp比udp快?

时间:2020-12-12 20:57:35
我做了一个试验,写了两个循环的阻塞发送/接收的程序,其中一个使用tcp,另一个使用udp,循环次数100到10000次,每次发送大小为256个字节,测试发现基于tcp的程序总是要比基于udp的程序快上三倍左右,很是不解,请高手指教

38 个解决方案

#1


事实说明tcp协议现在已经实现得很好了。比自己写UPD模仿TCP经济高效。

#2


UDP 是每次通讯都要建立链路。
TCP 第一次通讯建立链路后就一直在用直到断开!

所以发送比较频繁的还是用UDP的比TCP的好点!

#3


楼上胡扯,不懂不要胡乱下结论。

误导别人。

#4


“所以发送比较频繁的还是用UDP的比TCP的好点!”
说错了:是TCP比UDP好!

楼上的???

#5


lyck没有说错,有没有链路是IP层以下才关心的问题,和TCP/UDP没有关系。如果TCP有虚拟链路的话,UDP也是一样有的。

#6


LZ的试验其实一点也不能说明问题,LZ得出TCP快的结论,原因是使用了阻塞式发送,TCP send会被压到系统协议栈,从而直接返回,而UDP send可能要等到整个发送确实完成以后才返回,所以反而慢。判断快慢不能这样来的。在有些情况下TCP还会把多个封包合成一个来发送了,按照LZ这种测法,岂不是差距更大?

对一般的应用来说,可以这么说,TCP是优于UDP的,但不是所有的场合,要看情况。首先搞清楚了TCP的窗口和重发机制再来判断到底是优先TCP还是UDP。

#7


上面只是我个人的想法,谢谢ensoniq!

#8


在协议的层面上,TCP每次都要握手,而UDP理论上可以不必握手,但是实际应用上不能这样,最多只能把3次握手降低到两次。其实TCP和UDP的差别主要不是在于面向连接与否,也不在于可靠与否,可靠与否可以通过UDP仿TCP的方式实现,实际上Xbox就是这样做的,TCP的窗口协议只是一种算法。最大的差别是TCP的窗口协议是定死的算法,而UDP自己实现的话可以根据实际情况细调。TCP的窗口算法是标准算法,适合于Internet上的绝大部分应用需求,自定义的只有在特定的场合用到。

#9


系统协议栈有多大?如果send或recv太多会否栈区爆满而丢失数据? 

#10


也就是
如果发送方十分钟之内send佐1000000KB数据,
而接收方十分钟后再执行recv,甘数据会否丢失?  

谢谢 ensoniq !

#11


一般来说..... 会爆,但不会丢失,因为send有返回值,可以从中检测出socket发送buffer满,接下来由应用程序决定延后重发或者其他任意的对应。

但不是绝对... 这个问题扯远了。总之发送的程序一定不能忽略send的返回值,要有对应,否则这里就有bug。

#12


tcp--send 将数据由应用层拷贝到系统缓冲,交给IP层,等待对方的ACK然后返回
udp--sendto仅仅是将数据交给IP层后,就返回

对于单个小分组(256bit),从速度讲,udp一定比TCP快

#13


至于楼主的情况,不能说明任何问题

可能原因如下,仅供参考:
1.TCP可以连续发送多个分组,配合的是经受延时的ACK(选择性ACK)
2.
  慢启动:连接上最初只允许传输一个报文段,然后在发送下一个报文段之前必须等待接收它的确认。当报文段2被接收后,就可以再发送两个报文段。以此类推....直到达到最大MTU
  所以TCP通过慢启动机制可以提高吞吐量

3.nagle

#14


可以使用tcpdump
察看数据传输过程

#15


阻塞式发送应该是不用等ack的,不然如果ping是300你就要等300ms函数才会返回了。

#16


1.无论是否阻塞,只要是TCP,发送数据必须等到对方ACK,如果超时,或被对方设置RST,则会重传数据

2.ping程序使用的是ICMP

#17


如果发送方十分钟之内send佐1000000KB数据,
而接收方十分钟后再执行recv,甘数据会否丢失?  

---------------------------------------------
这种情况下,你根本没有机会发送那么大的数据

填满接收缓冲后,其余的数据都将被丢弃
TCP对这部分数据会重传,但TCP的滑动窗口已经填满,没有系统缓冲去接收这部分数据
最终还是被丢弃,导致数据丢失

只是理论上的分析,可以用TCPDUMP看看结果

#18


关闭nagle算法或者加大数据包到1450字节 再试

#19


楼上,人家LZ问的是函数返回时间,照你那么说,如果接受方不发送ack,你的函数调用就一直不返回了?还要一直等到超时?TCP的超时请问一般是多少请问?你听说过一个函数调用要花那么多时间的吗?况且如果你的说法成立,LZ的试验是根本不可能得出这样的结果的。

另外,一个封包的往返时间和ICMP或者IP有联系吗?你说我是TCP包,网络就会给你优先发送?

说要等ack再函数返回那肯定是不对的。

我猜正解应该是这样,确实应该是Nagle的关系,这一点楼上说的没错。因为send的数据被推到了协议栈,协议栈又根据Nagle合并了封包,所以网络实际发送的封包数量,TCP比UDP少很多,特别是这种小包,再因为底层有IP包头等开销,同样的数据量,当然发包的次数越少效率越高,这就是为什么LZ会得到这样的结果。

send只有在本地发送buffer满的时候才有可能阻塞。如果一开始就阻塞,要滑动窗口协议还有什么用?至于本地buffer如何会满,就要看ack什么时候收到了,一开始无论有没有ack都是不会满的,buffer至少有几十K,ack的作用只是用来移动滑动窗口一侧的,另一侧发送的当时就移动。

#20


>因为send有返回值,可以从中检测出socket发送buffer满,接下来由应用程序决定延后重发或者其他任意的对应。

这个不好意思,说的是非阻塞的情况,如果是阻塞的话,当时就不会返回。是根本没有机会发送。  
 

#21


至于楼主的情况,不能说明任何问题

可能原因如下,仅供参考:
1.TCP可以连续发送多个分组,配合的是经受延时的ACK(选择性ACK)
2.
  慢启动:连接上最初只允许传输一个报文段,然后在发送下一个报文段之前必须等待接收它的确认。当报文段2被接收后,就可以再发送两个报文段。以此类推....直到达到最大MTU
  所以TCP通过慢启动机制可以提高吞吐量

3.nagle
------------------------------------

关于楼主的问题,已经做了分析



#22


现在讨论的是另外一个话题
----------------------------------------
*************************************
TCP send会被压到系统协议栈,从而直接返回,而UDP send可能要等到整个发送确实完成以后才返回,所以反而慢。
*************************************

------------------------------------------
看到你的 回帖,我补充的是这个问题

#23


ensoniq兄台:现在讨论的是TCP send

对于TCP的send操作,并不是每一次都需要ACK,但一定需要ACK
对于较早版本的tcp,的确是每一次send,都需要一个ack确认,但这种方式性能受到很大影响
目前的改进版本,并不是每一个send,都需要ACK,而是经受延时的ACK,即选择性ACK
比如TCP一次发送3个分组,才返回一个ACK,但必须有ACK,才能继续发送

滑动窗口的原理也一样,发送端只有接收到peer的ACK,才能移动窗口右沿
否则当窗口大小为0,将 停止发送
可以通过tcpdump很清楚看到这一点

************************
对于你的问题:
如果接受方不发送ack,你的函数调用就一直不返回了?还要一直等到超时?**************************
如何发送端的,滑动窗口被填满,而接收方不发回ACK,函数调用的确不返回,一直等到超时




#24


你是在LAN还是Internet上测试。我想tcp除了连接外就是数据验证重传机制耗时;而UDP每次都要建立连接然后断开连接(当然这些都是由udp本身控制的)但不做数据验证。我认为LAN比Internet的网络环境普遍好一些,在LAN总tcp快一些,而在Internet已许udp就要快一些哟。

#25


loverx是个明白人

我认为任何情况下UDP都比TCP快!!!!这是从原理上决定的实事

#26


客户端看上去TCP比UDP快,我想是可能TCP回把缓冲去添满再发送,而UDP每次调用都发送后再返回的

所以实际上TCP实际发送次数少与UDP

#27


当然是发大量数据的时候

#28


楼主瞎掰吧,别去误导大家了。
看看路由协议,有用TCP的么?

#29


ensoniq() ( ) 信誉:100    Blog   加为好友  2007-3-1 17:14:01  得分: 0  

UDP要握手?我第一听说,而且还要2次!没听过,长见识了,哈哈哈

#30


你可以把UDP connect, 然后再试试. 某些研究表明连接的UDP速度比不连接快1/3.

#31


这位同学,我就说了那么一句话,犯得着你断章取义地来叫板吗?

#32


像你这样的没有听说过的事情多了去了,不握手你也能确定对端状态是否正常?也能建立你自身的状态机?你以为像TCP一样检查一下连接状态是否正常就可以了?还是只要超时判定一下就完了?你以为TCP的状态机是怎么来的?靠你写的代码设定进去的?

跟你这样的废什么话..我还真是有空了来。

#33


UDP,只做了薄薄的一次封装IP包,

#34


ideawu() 
你可以把UDP connect, 然后再试试. 某些研究表明连接的UDP速度比不连接快1/3.
------------------------------------------------------------------------------

真的吗,这个研究的出处在哪里,什么平台下的实验啊

#35


LZ,你实验数据接收都成功了吗?
按理论说应该是UDP快,TCP有验证重发之类的,UDP不管这些

#36


to loverx(烟花---俺想有系列之俺想有部车):

  ----------------------------------------------------------------------------
  "如果发送方十分钟之内send佐1000000KB数据,
  而接收方十分钟后再执行recv,甘数据会否丢失?

  ---------------------------------------------
  这种情况下,你根本没有机会发送那么大的数据

  填满接收缓冲后,其余的数据都将被丢弃
  TCP对这部分数据会重传,但TCP的滑动窗口已经填满,没有系统缓冲去接收这部分数据
  最终还是被丢弃,导致数据丢失

  只是理论上的分析,可以用TCPDUMP看看结果"
  ----------------------------------------------------------------------------


不要想当然, 自己动手试试再说!

#37


不同意 Mypiger(深圳 step by step)所说
TCP,UDP均是基于IP层,为何TCP可靠?
加了相应的控制机制,如重传机制,排序机制,流量控制 等,大量数据应该是用TCP更好吧,除非自己基于UDP加一些类似TCP的控制机制来确保数据传输的可靠性,根据具体的应用,可以灵活些,三次握手其实也是来保证可靠的
建议lz去读《TCP/IP详解》。

#38


基本概念,都混淆不清

#1


事实说明tcp协议现在已经实现得很好了。比自己写UPD模仿TCP经济高效。

#2


UDP 是每次通讯都要建立链路。
TCP 第一次通讯建立链路后就一直在用直到断开!

所以发送比较频繁的还是用UDP的比TCP的好点!

#3


楼上胡扯,不懂不要胡乱下结论。

误导别人。

#4


“所以发送比较频繁的还是用UDP的比TCP的好点!”
说错了:是TCP比UDP好!

楼上的???

#5


lyck没有说错,有没有链路是IP层以下才关心的问题,和TCP/UDP没有关系。如果TCP有虚拟链路的话,UDP也是一样有的。

#6


LZ的试验其实一点也不能说明问题,LZ得出TCP快的结论,原因是使用了阻塞式发送,TCP send会被压到系统协议栈,从而直接返回,而UDP send可能要等到整个发送确实完成以后才返回,所以反而慢。判断快慢不能这样来的。在有些情况下TCP还会把多个封包合成一个来发送了,按照LZ这种测法,岂不是差距更大?

对一般的应用来说,可以这么说,TCP是优于UDP的,但不是所有的场合,要看情况。首先搞清楚了TCP的窗口和重发机制再来判断到底是优先TCP还是UDP。

#7


上面只是我个人的想法,谢谢ensoniq!

#8


在协议的层面上,TCP每次都要握手,而UDP理论上可以不必握手,但是实际应用上不能这样,最多只能把3次握手降低到两次。其实TCP和UDP的差别主要不是在于面向连接与否,也不在于可靠与否,可靠与否可以通过UDP仿TCP的方式实现,实际上Xbox就是这样做的,TCP的窗口协议只是一种算法。最大的差别是TCP的窗口协议是定死的算法,而UDP自己实现的话可以根据实际情况细调。TCP的窗口算法是标准算法,适合于Internet上的绝大部分应用需求,自定义的只有在特定的场合用到。

#9


系统协议栈有多大?如果send或recv太多会否栈区爆满而丢失数据? 

#10


也就是
如果发送方十分钟之内send佐1000000KB数据,
而接收方十分钟后再执行recv,甘数据会否丢失?  

谢谢 ensoniq !

#11


一般来说..... 会爆,但不会丢失,因为send有返回值,可以从中检测出socket发送buffer满,接下来由应用程序决定延后重发或者其他任意的对应。

但不是绝对... 这个问题扯远了。总之发送的程序一定不能忽略send的返回值,要有对应,否则这里就有bug。

#12


tcp--send 将数据由应用层拷贝到系统缓冲,交给IP层,等待对方的ACK然后返回
udp--sendto仅仅是将数据交给IP层后,就返回

对于单个小分组(256bit),从速度讲,udp一定比TCP快

#13


至于楼主的情况,不能说明任何问题

可能原因如下,仅供参考:
1.TCP可以连续发送多个分组,配合的是经受延时的ACK(选择性ACK)
2.
  慢启动:连接上最初只允许传输一个报文段,然后在发送下一个报文段之前必须等待接收它的确认。当报文段2被接收后,就可以再发送两个报文段。以此类推....直到达到最大MTU
  所以TCP通过慢启动机制可以提高吞吐量

3.nagle

#14


可以使用tcpdump
察看数据传输过程

#15


阻塞式发送应该是不用等ack的,不然如果ping是300你就要等300ms函数才会返回了。

#16


1.无论是否阻塞,只要是TCP,发送数据必须等到对方ACK,如果超时,或被对方设置RST,则会重传数据

2.ping程序使用的是ICMP

#17


如果发送方十分钟之内send佐1000000KB数据,
而接收方十分钟后再执行recv,甘数据会否丢失?  

---------------------------------------------
这种情况下,你根本没有机会发送那么大的数据

填满接收缓冲后,其余的数据都将被丢弃
TCP对这部分数据会重传,但TCP的滑动窗口已经填满,没有系统缓冲去接收这部分数据
最终还是被丢弃,导致数据丢失

只是理论上的分析,可以用TCPDUMP看看结果

#18


关闭nagle算法或者加大数据包到1450字节 再试

#19


楼上,人家LZ问的是函数返回时间,照你那么说,如果接受方不发送ack,你的函数调用就一直不返回了?还要一直等到超时?TCP的超时请问一般是多少请问?你听说过一个函数调用要花那么多时间的吗?况且如果你的说法成立,LZ的试验是根本不可能得出这样的结果的。

另外,一个封包的往返时间和ICMP或者IP有联系吗?你说我是TCP包,网络就会给你优先发送?

说要等ack再函数返回那肯定是不对的。

我猜正解应该是这样,确实应该是Nagle的关系,这一点楼上说的没错。因为send的数据被推到了协议栈,协议栈又根据Nagle合并了封包,所以网络实际发送的封包数量,TCP比UDP少很多,特别是这种小包,再因为底层有IP包头等开销,同样的数据量,当然发包的次数越少效率越高,这就是为什么LZ会得到这样的结果。

send只有在本地发送buffer满的时候才有可能阻塞。如果一开始就阻塞,要滑动窗口协议还有什么用?至于本地buffer如何会满,就要看ack什么时候收到了,一开始无论有没有ack都是不会满的,buffer至少有几十K,ack的作用只是用来移动滑动窗口一侧的,另一侧发送的当时就移动。

#20


>因为send有返回值,可以从中检测出socket发送buffer满,接下来由应用程序决定延后重发或者其他任意的对应。

这个不好意思,说的是非阻塞的情况,如果是阻塞的话,当时就不会返回。是根本没有机会发送。  
 

#21


至于楼主的情况,不能说明任何问题

可能原因如下,仅供参考:
1.TCP可以连续发送多个分组,配合的是经受延时的ACK(选择性ACK)
2.
  慢启动:连接上最初只允许传输一个报文段,然后在发送下一个报文段之前必须等待接收它的确认。当报文段2被接收后,就可以再发送两个报文段。以此类推....直到达到最大MTU
  所以TCP通过慢启动机制可以提高吞吐量

3.nagle
------------------------------------

关于楼主的问题,已经做了分析



#22


现在讨论的是另外一个话题
----------------------------------------
*************************************
TCP send会被压到系统协议栈,从而直接返回,而UDP send可能要等到整个发送确实完成以后才返回,所以反而慢。
*************************************

------------------------------------------
看到你的 回帖,我补充的是这个问题

#23


ensoniq兄台:现在讨论的是TCP send

对于TCP的send操作,并不是每一次都需要ACK,但一定需要ACK
对于较早版本的tcp,的确是每一次send,都需要一个ack确认,但这种方式性能受到很大影响
目前的改进版本,并不是每一个send,都需要ACK,而是经受延时的ACK,即选择性ACK
比如TCP一次发送3个分组,才返回一个ACK,但必须有ACK,才能继续发送

滑动窗口的原理也一样,发送端只有接收到peer的ACK,才能移动窗口右沿
否则当窗口大小为0,将 停止发送
可以通过tcpdump很清楚看到这一点

************************
对于你的问题:
如果接受方不发送ack,你的函数调用就一直不返回了?还要一直等到超时?**************************
如何发送端的,滑动窗口被填满,而接收方不发回ACK,函数调用的确不返回,一直等到超时




#24


你是在LAN还是Internet上测试。我想tcp除了连接外就是数据验证重传机制耗时;而UDP每次都要建立连接然后断开连接(当然这些都是由udp本身控制的)但不做数据验证。我认为LAN比Internet的网络环境普遍好一些,在LAN总tcp快一些,而在Internet已许udp就要快一些哟。

#25


loverx是个明白人

我认为任何情况下UDP都比TCP快!!!!这是从原理上决定的实事

#26


客户端看上去TCP比UDP快,我想是可能TCP回把缓冲去添满再发送,而UDP每次调用都发送后再返回的

所以实际上TCP实际发送次数少与UDP

#27


当然是发大量数据的时候

#28


楼主瞎掰吧,别去误导大家了。
看看路由协议,有用TCP的么?

#29


ensoniq() ( ) 信誉:100    Blog   加为好友  2007-3-1 17:14:01  得分: 0  

UDP要握手?我第一听说,而且还要2次!没听过,长见识了,哈哈哈

#30


你可以把UDP connect, 然后再试试. 某些研究表明连接的UDP速度比不连接快1/3.

#31


这位同学,我就说了那么一句话,犯得着你断章取义地来叫板吗?

#32


像你这样的没有听说过的事情多了去了,不握手你也能确定对端状态是否正常?也能建立你自身的状态机?你以为像TCP一样检查一下连接状态是否正常就可以了?还是只要超时判定一下就完了?你以为TCP的状态机是怎么来的?靠你写的代码设定进去的?

跟你这样的废什么话..我还真是有空了来。

#33


UDP,只做了薄薄的一次封装IP包,

#34


ideawu() 
你可以把UDP connect, 然后再试试. 某些研究表明连接的UDP速度比不连接快1/3.
------------------------------------------------------------------------------

真的吗,这个研究的出处在哪里,什么平台下的实验啊

#35


LZ,你实验数据接收都成功了吗?
按理论说应该是UDP快,TCP有验证重发之类的,UDP不管这些

#36


to loverx(烟花---俺想有系列之俺想有部车):

  ----------------------------------------------------------------------------
  "如果发送方十分钟之内send佐1000000KB数据,
  而接收方十分钟后再执行recv,甘数据会否丢失?

  ---------------------------------------------
  这种情况下,你根本没有机会发送那么大的数据

  填满接收缓冲后,其余的数据都将被丢弃
  TCP对这部分数据会重传,但TCP的滑动窗口已经填满,没有系统缓冲去接收这部分数据
  最终还是被丢弃,导致数据丢失

  只是理论上的分析,可以用TCPDUMP看看结果"
  ----------------------------------------------------------------------------


不要想当然, 自己动手试试再说!

#37


不同意 Mypiger(深圳 step by step)所说
TCP,UDP均是基于IP层,为何TCP可靠?
加了相应的控制机制,如重传机制,排序机制,流量控制 等,大量数据应该是用TCP更好吧,除非自己基于UDP加一些类似TCP的控制机制来确保数据传输的可靠性,根据具体的应用,可以灵活些,三次握手其实也是来保证可靠的
建议lz去读《TCP/IP详解》。

#38


基本概念,都混淆不清