如何理解TCP的面向连接和UDP的无连接(不面向连接)?

在理解TCP和UDP中,一个是面向连接的传输协议,一个是不面向连接的协议。怎么能够更好的理解他们的不同呢?

这是我在知乎上看到的一个问题,回答中有非常形象生动的例子,所以总结一下。

参考:https://www.zhihu.com/question/51388497

 

一、有趣的回答一(狗男女版本)

亚当和夏娃分别生活在两个山头,山头之间是万丈深渊,亚当采集野果需要分享给夏娃。假设亚当需要给夏娃10个野果,否则她会饿死。

如果他们之间有一条索道(直接的物理连接),野果可以顺着索道滑到夏娃那一边,那就没有我们什么事了…

事实上山头之间没有索道,但是亚当何等聪明,于是他想出了两个方法(TCP和UDP):

(1)TCP

1、建立链接

亚当对着夏娃大喊:爱妃,你听得到吗?

夏娃回应:孩他爹,我听得到!

亚当接着喊:那好,我扔果子给你吃,你接到果子就喊一声,一共十个。

2、运送货物

于是亚当开始扔第一个,夏娃喊收到了一个。

亚当扔第二个,夏娃喊收到两个。

3、超时重传(timeout retransmit)

亚当扔第三个,可是夏娃迟迟没有回音,亚当意识到可能果子落到悬崖了,于是重新扔,夏娃喊收到第三个。

4、Advertised window size = 0

于是亚当连续扔了第四、五、六个,夏娃急了:孩他爹,慢点扔,臣妾忙不过来了!

5、Advertised window size > 0

于是亚当坐下休息,爱妃又开始叫了:继续扔吧。

于是亚当开始扔第七个,夏娃喊收到七个。

6、关闭连接

终于亚当扔完了,亚当喊:爱妃,果子扔完了,寡人去忙别的了。

夏娃回复:好的,我也休息一下,再见

亚当:再见

以上的过程类似TCP连接的过程,TCP是一个虚拟链接。

7、何为虚拟链接

物理链接是实实在在存在的,看得见摸得着,比如索道。

虚拟链接是不存在的,看不见摸不着,通过双向的消息、消息确认来模拟物理链接。

(2)UDP

亚当和夏娃吵架了,任凭亚当如何大声喊,夏娃躲在树林后生闷气,一声不响,亚当害怕夏娃饿死,于是开始自说自话朝着夏娃的山头扔玉米棒子:

一个、两个、三个…..

一共扔了十个,但最终扔到对方山头到底有几个,亚当没有底,也许有的玉米棒子落到悬崖了,但是这个效率高啊,可以连续扔,以前扔10个果子需要一分钟,现在只需要20秒。

亚当扔果子、扔玉米都有可能扔到悬崖下,但是扔果子为何可以确保对方收到十个?

那是因为夏娃收到一个果子,然后喊收到了,如果没有收到,亚当就重新扔,直到夏娃说收到了。

但是,夏娃并没有确认是否收到了玉米棒子,亚当没有办法知道夏娃是否收到了,所以无法重新扔。

二、有趣的回答二(查水表版本)

(1)TCP

“我给你讲一个关于TCP的笑话。”

“好的你给我讲一个关于TCP的笑话。”

“好的。”

“苟。这是第一个字。”

“第一个字收到,请发第二个字。”

“利。这是第二个字。”

“第二个字收到,请发第三个字。”

“国。这是第三个字。”

“国。这是第三个字。”

“第三个字收到,请发第四个字。”

“家……”

……

“我讲完了。”

“好的。”

“我听完了。”

“好的。”

(2)UDP

“我给你讲一个关于UDP的笑话。”

“咦我好像听见一个关笑P话的U……?咦这苟啊国家啊这什么什么之是啥玩意?我让应用层看看……应用层说应该是两句诗?”

这里有个问题,为什么UDP收到的数据会乱序呢?

那是因为信道不一定能保证把每个报文都按顺序传送,可能丢包,也可能走了一条高延时的路径。UDP没有四层协议的seq和ack,只能靠七层应用层来辨明收到的数据是什么意思。

既然UDP可能造成丢包 + 乱序,那么UDP协议有何优势?又有什么应用呢?

UDP的优势在于快,省去了发ack的过程。因此应用层必须具备验证完整性可靠性的机制。

在应用方面,UDP主要用于音频、视频之类的应用(流媒体),因为UDP不需要准确无误的信息传递。少一个像素(丢失一些细节)什么的不太会影响整体效果。

还有一点需要补充,很多人认为UDP是“不可靠的传输协议”,在可靠性上远远不如TCP。从UDP的特点出发,这是不可否认的。

但是,我们可以在上层应用层(UDP是传输层,我们动不了)增加可靠性机制,加上特定的错误恢复机制。通过这些方式,可以让UDP传输更加可靠(实际上,如果自己加上握手机制,错误重传机制,就有点像TCP了)。

三、有趣的回答三(笑话版本)

(1)TCP

1.三次握手

“我给你讲一个 TCP 的笑话吧?”

“给我讲一个 TCP 笑话呗!”

“好的,我会给你讲一个TCP 的笑话。”

2.TCP传输过程

“嗨,我想听一个 TCP 的笑话。”

“你好,你想听 TCP 的笑话么?”

“嗯,我想听一个 TCP 的笑话。”

“好的,我会给你讲一个TCP 的笑话。”

“好的,我会听一个TCP 的笑话。”

“你准备好听一个TCP 的笑话么?”

“嗯,我准备好听一个TCP 的笑话”

“OK,那我要发 TCP 笑话了。大概有 10 秒,20 个字。”

“嗯,我准备收你那个 10 秒时长,20 个字的笑话了。”

“抱歉,你的连接超时了。你好,你想听 TCP 的笑话么?”

关于这一段我有一些疑问:握手次数似乎超过了三次…是不是有些不对?个人认为可以这样解释:三次握手的过程应该是:“发送方询问,接收方确认接收,发送方确认发送”,这三个确认的流程被称为三次握手。只要有三次确认流程在,无论发送方接收方怎么交流尝试建立链接,都可以被称为三次握手。

顺带一提,三次握手的目的是让发送方接收方都进入准备状态,接下来是传数据的部分 不属于三次握手。

(2)UDP

我给你们讲个 UDP 的笑话吧!

到这里这个笑话就结束了。我想了一下,原来这是在黑UDP不建立可靠连接,导致接收方什么数据都收不到。

事实上,这个笑话还可以这样写,效果更好:

给个你我们讲 UDP 的话吧!

在丢包的基础上,进一步黑了UDP收到的数据会乱序的现象。

四、总结

把问题讲清楚不是特别难,但是要把问题解释得生动有趣就有难度了。

还是要多多学习,掌握抽象问题的能力。

发表评论

电子邮件地址不会被公开。 必填项已用*标注