Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >网络编程懒人入门(四):快速理解TCP和UDP的差异

网络编程懒人入门(四):快速理解TCP和UDP的差异

作者头像
JackJiang
发布于 2018-08-23 09:50:53
发布于 2018-08-23 09:50:53
8820
举报
文章被收录于专栏:即时通讯技术即时通讯技术

原作者:MeloDev,本文由即时通讯网重新修订发布,感谢原作者的无私分享。

1、前言

对于即时通讯开者新手来说,在开始着手编写IM或消息推送系统的代码前,最头疼的问题莫过于到底该选TCP还是UDP作为传输层协议。本文延续《网络编程懒人入门》系列文章的风格,通过快速对比分析 TCP 和 UDP 的区别,来帮助即时通讯初学者快速了解这些基础的知识点,从而在IM、消息推送等网络通信应用场景中能准确地选择合适的传输层协议。

另一篇文章《简述传输层协议TCP和UDP的区别》也阐述了类似的内容,希望能为您提供更多的参考。

(本文同步发布于:http://www.52im.net/thread-1160-1-1.html

2、系列文章

本文是系列文章中的第4篇,本系列文章的大纲如下:

网络编程懒人入门(一):快速理解网络通信协议(上篇)

网络编程懒人入门(二):快速理解网络通信协议(下篇)

网络编程懒人入门(三):快速理解TCP协议一篇就够

网络编程懒人入门(四):快速理解TCP和UDP的差异》(本文)

3、参考资料

TCP/IP详解-第11章·UDP:用户数据报协议

TCP/IP详解-第17章·TCP:传输控制协议

TCP/IP详解-第18章·TCP连接的建立与终止

TCP/IP详解-第21章·TCP的超时与重传

通俗易懂-深入理解TCP协议(上):理论基础

通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理

理论经典:TCP协议的3次握手与4次挥手过程详解

理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程

技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)

计算机网络通讯协议关系图(中文珍藏版)

高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少

高性能网络编程(二):上一个10年,著名的C10K并发连接问题

高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了

高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索

不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)

不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)

不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT

不为人知的网络编程(四):深入研究分析TCP的异常关闭

不为人知的网络编程(五):UDP的连接性和负载均衡

不为人知的网络编程(六):深入地理解UDP协议并用好它

简述传输层协议TCP和UDP的区别

UDP中一个包的大小最大能多大?

为什么QQ用的是UDP协议而不是TCP协议?

移动端即时通讯协议选择:UDP还是TCP?

4、建立连接方式的差异

4.1 TCP

说到 TCP 建立连接,相信大多数人脑海里肯定可以浮现出一个词,没错就是--“三次握手”。TCP 通过“三次握手”来建立连接,再通过“四次挥手”断开一个连接。在每次挥手中 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 建立连接的“三次握手”。

4.2 UDP

我们都知道 TCP 是面向连接的、可靠的、有序的传输层协议,而 UDP 是面向数据报的、不可靠的、无序的传输协议,所以 UDP 压根不会建立什么连接。

就好比发短信一样,UDP 只需要知道对方的 ip 地址,将数据报一份一份的发送过去就可以了,其他的作为发送方,都不需要关心。

(关于TCP的3次握手和4次挥手文章,可详见《理论经典:TCP协议的3次握手与4次挥手过程详解》、《理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程》)

5、数据发送方式的差异

关于 TCP、UDP 之间数据发送的差异,可以体现二者最大的不同之处:

TCP: 由于 TCP 是建立在两端连接之上的协议,所以理论上发送的数据流不存在大小的限制。但是由于缓冲区有大小限制,所以你如果用 TCP 发送一段很大的数据,可能会截断成好几段,接收方依次的接收。 UDP: 由于 UDP 本身发送的就是一份一份的数据报,所以自然而然的就有一个上限的大小。

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

1)UDP协议本身,UDP协议中有16位的UDP报文长度,那么UDP报文长度不能超过2^16=65536; 2)以太网(Ethernet)数据帧的长度,数据链路层的MTU(最大传输单元); 3)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

(有关UDP协议的最大包长限制,详见《UDP中一个包的大小最大能多大?》)

6、数据有序性的差异

我们再来谈谈数据的有序性。

6.1 TCP

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

6.2 UDP

而 UDP 协议则要奔放的多,无论 server 端无论缓冲池的大小有多大,接收 client 端发来的消息总是一个一个的接收。并且由于 UDP 本身的不可靠性以及无序性,如果 client 发送了 1、2、3 这三个数据报过来,server 端接收到的可能是任意顺序、任意个数三个数据报的排列组合。

7、可靠性的差异

其实大家都知道 TCP 本身是可靠的协议,而 UDP 是不可靠的协议。

7.1 TCP

TCP 内部的很多算法机制让他保持连接的过程中是很可靠的。比如:TCP 的超时重传、错误重传、TCP 的流量控制、阻塞控制、慢热启动算法、拥塞避免算法、快速恢复算法 等等。所以 TCP 是一个内部原理复杂,但是使用起来比较简单的这么一个协议。

7.2 UDP

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

所以来研究下,什么情况会导致 UDP 丢包:

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

8、使用场景总结

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

先来说 UDP 的吧,有很多人都会觉得 UDP 与 TCP 相比,在性能速度上是占优势的。因为 UDP 并不用保持一个持续的连接,也不需要对收发包进行确认。但事实上经过这么多年的发展 TCP 已经拥有足够多的算法和优化,在网络状态不错的情况下,TCP 的整体性能是优于 UDP 的。

那在什么时候我们非用 UDP 不可呢?

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

以上我们说了 UDP 的使用场景,在此之外的其他情况,使用 TCP 准没错。

(原文链接:点此进入,有改动)

(本文同步发布于:http://www.52im.net/thread-1160-1-1.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.10.27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?
老于网络编程熟手来说,在测试和部署网络通信应用(比如IM聊天、实时音视频等)时,如果发现网络连接超时,第一时间想到的就是使用Ping命令Ping一下服务器看看通不通。甚至在有些情况下通过图形化的Ping命令工具对目标网络进行长测(比如:《两款增强型Ping工具:持续统计、图形化展式网络状况 [附件下载]》、《网络测试:Android版多路ping命令工具EnterprisePing[附件下载]》),可以得出当前网络通信的网络延迟、网络丢包率、网络抖动等等有价值信息。
JackJiang
2018/09/21
1.6K0
《C++ 网络编程:高效实现 TCP/IP 与 UDP 通信》
在当今数字化时代,网络编程在各个领域都有着至关重要的地位。对于 C++开发者来说,掌握高效的网络编程方法,特别是 TCP/IP 和 UDP 通信的实现,是一项极具价值的技能。这篇文章将深入探讨在 C++中实现高效网络编程的要点和技巧。
程序员阿伟
2024/12/09
2980
脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手
网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一。很多读者都知道“三次”和“四次”,但是如果问深入一点,他们往往都无法作出准确回答。
JackJiang
2018/08/29
9080
网络编程入门从未如此简单(二):假如你来设计TCP协议,会怎么做?
网络编程能力对于即时通讯技术开发者来说是基本功,而计算机网络又是网络编程的理论根基,因而深刻准确地理解计算机网络知识显然能夯实你的即时通讯应用的实践品质。 本文风格类似于《网络编程懒人入门》、《脑残式网络编程入门》两个系列,但通俗又不失内涵,简洁又不简陋,非常适合对计算机网络知识有向往但又有惧怕的网络编程爱好者们阅读,希望能给你带来不一样的网络知识入门视角。 本篇将运用通俗易懂的语言,配上细致精确的图片动画,循序渐进地引导你理解TCP协议的主要特性和技术原理,让TCP协议的学习不再如此枯燥和生涩,非常适合入门者阅读。
JackJiang
2021/02/24
5100
网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门
即时通讯网整理了大量的网络编程类基础文章和资料,包括《TCP/IP协议 卷1》、《[通俗易懂]深入理解TCP协议》系列、《网络编程懒人入门》系列、《不为人知的网络编程》系列、《P2P技术详解》系列、《高性能网络编程》系列、甚至还有图文并貌+实战代码的《NIO框架入门》等,目的是帮助即时通讯类应用的开发者,至少要掌握网络编程最基本的原理,所谓知其然更要知其所以然。尤其现在移动网络大行其道的时代,在网络环境如此复杂的情况下,能写好一套技术精湛、用户体验等俱佳的IM或消息推送系统,显然不是随便用用Netty、MINA、AFNetwoking、okhttp等服务端和客户端框架就能搞定的事。总之,即时通讯技术归根结底还是网络编程技术的应用,只有更深入地了解了网络编程及其相关知识,才能更好地写出优质的应用。
JackJiang
2018/08/29
1.1K0
JAVA高并发网络编程之TCP和UDP协议(八)
1、创建服务器套接字---分配内存、初始化 2、服务器套接字--侦听 3、建立与客户端配套的客户端套接字 4、与客户端通讯(可以多客户端) 5、关闭、销毁[服务器端相应套接字
IT架构圈
2020/11/09
9780
JAVA高并发网络编程之TCP和UDP协议(八)
可能会搞砸你的面试:你知道一个TCP连接上能发起多少个HTTP请求吗?
本文由原作者松若章原创发布,作者主页:zhihu.com/people/hrsonion/posts,感谢原作者的无私分享。
JackJiang
2019/08/05
1.7K0
可能会搞砸你的面试:你知道一个TCP连接上能发起多少个HTTP请求吗?
不为人知的网络编程(十六):深入分析与解决TCP的RST经典异常问题
TCP的经典异常问题无非就是丢包和连接中断,在这里我打算与各位聊一聊TCP的RST到底是什么?现网中的RST问题有哪些模样?我们如何去应对和解决?
JackJiang
2024/06/20
3470
不为人知的网络编程(十六):深入分析与解决TCP的RST经典异常问题
网络编程之快速搞懂TCP和UDP的区别
网络协议是每个搞网络通信应用开发(比如IM、推送、网关等等)的程序员都必须要掌握的基础知识,TCP/IP协议簇中有两个最具有代表性的传输层协议——分别是 TCP 和 UDP。
大忽悠爱学习
2022/05/06
5630
网络编程之快速搞懂TCP和UDP的区别
迈向高阶:优秀Android程序员必知必会的网络基础
网络通信一直是Android项目里比较重要的一个模块,Android开源项目上出现过很多优秀的网络框架,从一开始只是一些对HttpClient和HttpUrlConnection简易封装使用的工具类,到后来Google开源的比较完善丰富的Volley,再到如今比较流行的Okhttp、Retrofit。
JackJiang
2018/09/17
9740
网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接
本文原作者:“水晶虾饺”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动。
JackJiang
2018/08/29
2.2K0
网络编程懒人入门(一):快速理解网络通信协议(上篇)
论坛和群里常会有技术同行打算自已开发IM或者消息推送系统,很多时候连基本的网络编程理论(如网络协议等)都不了解,就贸然定方案、写代码,显得非常盲目且充满技术风险。
JackJiang
2018/08/23
9770
网络编程懒人入门(一):快速理解网络通信协议(上篇)
TCP和UDP详解
经历了上面的三次握手过程,客户端和服务端都确认了自己的接收、发送能力是正常的。之后就可以正常通信了。 每次都是接收到数据包的一方可以得到一些结论,发送的一方其实没有任何头绪。我虽然有发包的动作,但是我怎么知道我有没有发出去,而对方有没有接收到呢? 而从上面的过程可以看到,最少是需要三次握手过程的。两次达不到让双方都得出自己、对方的接收、发送能力都正常的结论。 其实每次收到网络包的一方至少是可以得到:对方的发送、我方的接收是正常的。而每一步都是有关联的,下一次的“响应”是由于第一次的“请求”触发,因此每次握手其实是可以得到额外的结论的。 比如第三次握手时,服务端收到数据包,表明看服务端只能得到客户端的发送能力、服务端的接收能力是正常的,但是结合第二次,说明服务端在第二次发送的响应包,客户端接收到了,并且作出了响应,从而得到额外的结论:客户端的接收、服务端的发送是正常的。
是阿超
2021/12/30
1K0
什么是网络编程
在计算机网络要做到井井有条的交换数据,就必须遵守一些事先约定好的规则,比如交换数据的格式、是否需要发送一个应答信息。这些规则被称为网络协议。
程序员Leo
2023/08/02
1.4K0
什么是网络编程
Android程序员必知必会的网络通信传输层协议——UDP和TCP
互联网发展至今已经高度发达,而对于互联网应用(尤其即时通讯技术这一块)的开发者来说,网络编程是基础中的基础,只有更好地理解相关基础知识,对于应用层的开发才能做到游刃有余。
JackJiang
2019/01/10
9230
网络编程懒人入门(三):快速理解TCP协议一篇就够1、前言2、系列文章3、参考资料4、TCP 协议的作用5、TCP 数据包的大小6、TCP 数据包的编号(SEQ) 7、TCP 数据包的组装 8、慢启动
本系列文章的前两篇《网络编程懒人入门(一):快速理解网络通信协议(上篇)》、《网络编程懒人入门(二):快速理解网络通信协议(下篇)》快速介绍了网络基本通信协议及理论基础,建议开始阅读本文前先读完此2篇文章。
JackJiang
2018/08/23
9560
网络编程懒人入门(三):快速理解TCP协议一篇就够1、前言2、系列文章3、参考资料4、TCP 协议的作用5、TCP 数据包的大小6、TCP 数据包的编号(SEQ)
7、TCP 数据包的组装
8、慢启动
网络编程懒人入门(五):快速理解为什么说UDP有时比TCP更有优势
对于即时通讯开者新手来说,在开始着手编写IM或消息推送系统的代码前,最头疼的问题莫过于到底该选TCP还是UDP作为传输层协议。本文延续《网络编程懒人入门》系列文章的风格,通过快速对比分析 TCP 和 UDP 的区别,来帮助即时通讯初学者快速了解这些基础的知识点,从而在IM、消息推送等网络通信应用场景中能准确地选择合适的传输层协议。
JackJiang
2018/08/23
1.1K0
网络编程懒人入门(五):快速理解为什么说UDP有时比TCP更有优势
移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”
本系列文章引用了腾讯技术专家樊华恒《海量之道系列文章之弱联网优化》的部分章节,感谢原作者。
JackJiang
2018/08/29
1.6K0
一文读懂高性能网络编程中的I/O模型
随着互联网的发展,面对海量用户高并发业务,传统的阻塞式的服务端架构模式已经无能为力。本文(和下篇《高性能网络编程(六):一文读懂高性能网络编程中的线程模型》)旨在为大家提供有用的高性能网络编程的I/O模型概览以及网络服务进程模型的比较,以揭开设计和实现高性能网络架构的神秘面纱。
JackJiang
2018/09/06
1.5K0
不为人知的网络编程(十一):从底层入手,深度分析TCP连接耗时的秘密
对于基于互联网的通信应用(比如IM聊天、推送系统),数据传递时使用TCP协议相对较多。这是因为在TCP/IP协议簇的传输层协议中,TCP协议具备可靠的连接、错误重传、拥塞控制等优点,所以目前在应用场景上比UDP更广泛一些。
JackJiang
2022/05/26
7040
不为人知的网络编程(十一):从底层入手,深度分析TCP连接耗时的秘密
推荐阅读
脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?
1.6K0
《C++ 网络编程:高效实现 TCP/IP 与 UDP 通信》
2980
脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手
9080
网络编程入门从未如此简单(二):假如你来设计TCP协议,会怎么做?
5100
网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门
1.1K0
JAVA高并发网络编程之TCP和UDP协议(八)
9780
可能会搞砸你的面试:你知道一个TCP连接上能发起多少个HTTP请求吗?
1.7K0
不为人知的网络编程(十六):深入分析与解决TCP的RST经典异常问题
3470
网络编程之快速搞懂TCP和UDP的区别
5630
迈向高阶:优秀Android程序员必知必会的网络基础
9740
网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接
2.2K0
网络编程懒人入门(一):快速理解网络通信协议(上篇)
9770
TCP和UDP详解
1K0
什么是网络编程
1.4K0
Android程序员必知必会的网络通信传输层协议——UDP和TCP
9230
网络编程懒人入门(三):快速理解TCP协议一篇就够1、前言2、系列文章3、参考资料4、TCP 协议的作用5、TCP 数据包的大小6、TCP 数据包的编号(SEQ) 7、TCP 数据包的组装 8、慢启动
9560
网络编程懒人入门(五):快速理解为什么说UDP有时比TCP更有优势
1.1K0
移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”
1.6K0
一文读懂高性能网络编程中的I/O模型
1.5K0
不为人知的网络编程(十一):从底层入手,深度分析TCP连接耗时的秘密
7040
相关推荐
脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档