共计 2388 个字符,预计需要花费 6 分钟才能阅读完成。
对于即时通讯开者老手来说,在开始着手编写 IM 或音讯推送零碎的代码前,最头疼的问题莫过于到底该选 TCP 还是 UDP 作为传输层协定。
TCP
说到 TCP 建设连贯,置信大多数人脑海里必定能够浮现出一个词,没错就是 –“三次握手”。TCP 通过“三次握手”来建设连贯,再通过“四次挥手”断开一个连贯。在每次挥手中 TCP 做了哪些操作呢?
咱们能够先明确一下 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 建设连贯的“三次握手”。
UDP
咱们都晓得 TCP 是面向连贯的、牢靠的、有序的传输层协定,而 UDP 是面向数据报的、不牢靠的、无序的传输协定,所以 UDP 压根不会建设什么连贯。
就好比发短信一样,UDP 只须要晓得对方的 ip 地址,将数据报一份一份的发送过来就能够了,其余的作为发送方,都不须要关怀。
数据发送形式的差别
对于 TCP、UDP 之间数据发送的差别,能够体现二者最大的不同之处:
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 的数据是有序的,假如你发送了数据 1、2、3,则只有发送端和接收端放弃连贯时,接收端收到的数据始终都是 1、2、3。
UDP
而 UDP 协定则要奔放的多,无论 server 端无论缓冲池的大小有多大,接管 client 端发来的音讯总是一个一个的接管。并且因为 UDP 自身的不可靠性以及无序性,如果 client 发送了 1、2、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 准没错。