快速理解TCP和UDP的差别

前言

最头疼的问题莫过于到底该选TCP仍是UDP做为传输层协议。经过快速对比分析 TCP 和 UDP 的区别,来帮助即时通信初学者快速了解这些基础的知识点,从而在IM、消息推送等网络通讯应用场景中能准确地选择合适的传输层协议。算法

创建链接方式的差别

TCP

说到 TCP 创建链接,相信大多数人脑海里确定能够浮现出一个词,没错就是--“三次握手”。TCP 经过“三次握手”来创建链接,再经过“四次挥手”断开一个链接。在每次挥手中 TCP 作了哪些操做呢?缓存

流程以下图所示(TCP的三次握手和四次挥手):网络

clipboard.png

上图就从客户端和服务端的角度,清楚的展现了 TCP 的三次握手和四次挥手。能够看到,当 TCP 试图创建链接时,三次握手指的是客户端主动触发了两次,服务端触发了一次。socket

咱们能够先明确一下 TCP 创建链接而且初始化的目标是什么呢?性能

  • 1初始化资源;
  • 2告诉对方个人序列号。

因此三次握手的次序是这样子的:优化

  1. client端首先发送一个SYN包告诉Server端个人初始序列号是X;
  2. Server端收到SYN包后回复给client一个ACK确认包,告诉client说我收到了;
  3. 接着Server端也须要告诉client端本身的初始序列号,因而Server也发送一个SYN包告诉client个人初始序列号是Y;
  4. Client收到后,回复Server一个ACK确认包说我知道了。

其中的 2 、3 步骤能够简化为一步,也就是说将 ACK 确认包和 SYN 序列化包一同发送给 Client 端。到此咱们就比较简单的解释了 TCP 创建链接的“三次握手”。spa

UDP

咱们都知道 TCP 是面向链接的、可靠的、有序的传输层协议,而 UDP 是面向数据报的、不可靠的、无序的传输协议,因此 UDP 压根不会创建什么链接。视频

就比如发短信同样,UDP 只须要知道对方的 ip 地址,将数据报一份一份的发送过去就能够了,其余的做为发送方,都不须要关心。server

数据发送方式的差别

关于 TCP、UDP 之间数据发送的差别,能够体现两者最大的不一样之处:ip

  • TCP:
    因为 TCP 是创建在两端链接之上的协议,因此理论上发送的数据流不存在大小的限制。可是因为缓冲区有大小限制,因此你若是用 TCP 发送一段很大的数据,可能会截断成好几段,接收方依次的接收。
  • UDP:
    因为 UDP 自己发送的就是一份一份的数据报,因此天然而然的就有一个上限的大小。

那么每次 UDP 发送的数据报大小由哪些因素共同决定呢?

  • UDP协议自己,UDP协议中有16位的UDP报文长度,那么UDP报文长度不能超过2^16=65536;
  • 以太网(Ethernet)数据帧的长度,数据链路层的MTU(最大传输单元);
  • socket的UDP发送缓存区大小

先来看第一个因素,UDP 自己协议的报文长度为 2^16 - 1,UDP 包头占 8 个字节,IP 协议自己封装后包头占 20 个字节,因此最终长度为: 2^16 - 1 - 20 - 8 = 65507 字节。

只看第一个因素有点理想化了,由于 UDP 属于不可靠协议,咱们应该尽可能避免在传输过程当中,数据包被分割。因此这里有一个很是重要的概念 MTU -- 也就是最大传输单元。

在 Internet 下 MTU 的值为 576 字节,因此在 internet 下使用 UDP 协议,每一个数据报最大的字节数为: 576 - 20 - 8 = 548

数据有序性的差别

TCP

对于 TCP 来讲,自己 TCP 有着超时重传、错误重传、还有等等一系列复杂的算法保证了 TCP 的数据是有序的,假设你发送了数据 一、二、3,则只要发送端和接收端保持链接时,接收端收到的数据始终都是 一、二、3。

UDP

而 UDP 协议则要奔放的多,不管 server 端不管缓冲池的大小有多大,接收 client 端发来的消息老是一个一个的接收。

而且因为 UDP 自己的不可靠性以及无序性,若是 client 发送了 一、二、3 这三个数据报过来,server 端接收到的多是任意顺序、任意个数三个数据报的排列组合。

可靠性的差别

其实你们都知道 TCP 自己是可靠的协议,而 UDP 是不可靠的协议。

TCP

TCP 内部的不少算法机制让他保持链接的过程当中是很可靠的。好比:TCP 的超时重传、错误重传、TCP 的流量控制、阻塞控制、慢热启动算法、拥塞避免算法、快速恢复算法 等等。

因此 TCP 是一个内部原理复杂,可是使用起来比较简单的这么一个协议。

UDP

UDP 是一个面向非链接的协议,UDP 发送的每一个数据报带有本身的 IP 地址和接收方的 IP 地址,它自己对这个数据报是否出错,是否到达不关心,只要发出去了就行了。

因此来研究下,什么状况会致使 UDP 丢包:

  • 数据报分片重组丢失:在文章以前咱们就说过,UDP 的每一个数据报大小多少最合适,事实上 UDP 协议自己规定的大小是 64kb,可是在数据链路层有 MTU 的限制,大小大概在 5kb,因此当你发送一个很大的 UDP 包的时候,这个包会在 IP 层进行分片,而后重组。这个过程就有可能致使分片的包丢失。UDP 自己有 CRC 检测机制,会抛弃掉丢失的 UDP 包;
  • UDP 缓冲区填满:当 UDP 的缓冲区已经被填满的时候,接收方尚未处理这部分的 UDP 数据报,这个时候再过来的数据报就没有地方能够存了,天然就都被丢弃了。

使用场景总结

在文章最后的一部分,聊聊 TCP、UDP 使用场景。

先来讲 UDP 的吧,有不少人都会以为 UDP 与 TCP 相比,在性能速度上是占优点的。

由于 UDP 并不用保持一个持续的链接,也不须要对收发包进行确认。

但事实上通过这么多年的发展 TCP 已经拥有足够多的算法和优化,在网络状态不错的状况下,TCP 的总体性能是优于 UDP 的。

那在何时咱们非用 UDP 不可呢?

  • 对实时性要求高:好比实时会议,实时视频这种状况下,若是使用 TCP,当网络很差发生重传时,画面确定会有延时,甚至越堆越多。若是使用 UDP 的话,即便偶尔丢了几个包,可是也不会影响什么,这种状况下使用 UDP 比较好;
  • 多点通讯:TCP 须要保持一个长链接,那么在涉及多点通信的时候,确定须要和多个通讯节点创建其双向链接,而后有时在NAT环境下,两个通讯节点创建其直接的 TCP 链接不是一个容易的事情,而 UDP 能够无需保持链接,直接发就能够了,因此成本会很低,并且穿透性好。这种状况下使用 UDP 也是没错的。

以上咱们说了 UDP 的使用场景,在此以外的其余状况,使用 TCP 准没错。

毕竟有一句话嘛:

when in doubt,use TCP。
相关文章
相关标签/搜索