三次握手
客户端:我要接你发信息了
服务端:你发吧
客户端:我开始发了(ing)
为什么需要三次握手,两次不行吗?
如果客户端只能发信息
,而不能收信息
当服务端向客户端发信息时,客户端收不到,就会一直占用连接,浪费资源
- 第一次握手:客户端发送网络包,服务端收到了。
这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。 - 第二次握手:服务端发包,客户端收到了。
这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。 - 第三次握手:客户端发包,服务端收到了。
这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常
三次的目的:确认双方的接收与发送能力是否正常
四次挥手
客户端:我好了,不需要再给你传送信息了
服务端:知道了
服务端:我也好了
客户端:我收到你最后发的信息了,你可以安息了
如果没有最后一次挥手,万一服务端最后发送的消息
客户端没有收到呢?
TCP 是面向连接的
亚当和夏娃分别生活在两个山头,山头之间是万丈深渊,亚当采集野果需要分享给夏娃,如果他们之间有一条索道(物理连接),野果可以顺着索道滑到夏娃那一边,那就没有车小胖什么事了。
事实上山头之间没有索道,但是亚当何等聪明,于是他想出了一个方法,假设亚当需要给夏娃10个野果,否则她会饿死。
连接建立
亚当对着夏娃大喊:爱妃,你听得到吗?
夏娃回应:孩他爹,我听得到!
亚当接着喊:那好,我扔果子给你吃,你接到果子就喊一声,一共十个。
运送货物
于是亚当开始扔第一个,夏娃喊收到了一个。
亚当扔第二个,夏娃喊收到两个。
超时重传 ( timeout retransmit)
亚当扔第三个,可是夏娃迟迟没有回音,亚当意识到可能果子落到悬崖了,于是重新扔,夏娃喊收到第三个。
Advertised window size = 0
于是亚当连续扔了第四、五、六个,夏娃急了:孩他爹,慢点扔,臣妾忙不过来了…
Advertised window size > 0
于是亚当坐下休息,爱妃又开始叫了:继续扔吧。
亚当开始扔第七个,夏娃喊收到七个。
…
关闭连接
终于亚当扔完了,亚当喊:爱妃,果子扔完了,寡人去忙别的了。
夏娃回复:好的,我也休息一下,再见
亚当:再见
以上的过程类似TCP连接的过程,TCP是一个虚拟连接。
何为虚拟连接?
和物理连接所对应,物理连接是实实在在存在的,看得见摸得着,比如索道。而虚拟连接是不存在的,看不见摸不着,通过双向的消息、消息确认来模拟物理连接。
由于有确认机制,亚当可以确保夏娃可以收到10个果子。
那接下来再谈谈什么是无连接的UDP?
亚当和夏娃吵架了,任凭亚当如何大声喊,夏娃躲在树林后生闷气,一声不响,亚当害怕夏娃饿死,于是开始自说自话朝着夏娃的山头扔玉米棒子:
一个、两个、三个…
一共扔了十个,但最终扔到对方山头到底有几个,亚当没有底,也许有的玉米棒子落到悬崖了,但是这个效率高啊,可以连续扔,以前扔10个果子需要一分钟,现在只需要20秒。
亚当扔果子、扔玉米都有可能扔到悬崖下,但是扔果子为何可以确保对方收到十个?那是因为夏娃收到一个果子,然后喊收到了,如果没有收到,亚当就重新扔,直到夏娃说收到了。而扔玉米棒子对方没有确认,所以对于丢弃的情况无法知道,也无法重新扔。