前言
关于网络,我想各位大兄弟是又爱又恨
爱的是各种强大的技术框架早已把网络封装的又简单又好用,天天request,fetchData用的飞起
恨的是每次面试的时候都要被问:
“HTTP和TCP有什么区别?”
“HTTP和Socket有什么区别?”
“什么是三次握手,四次挥手?”
“为什么不两次握手要三次握手?”
“为什么不三次挥手要四次挥手”
“为什么四次挥手的时候要等待2msl?”
“http1.0 http1.1 http2.0 有什么区别?”
“http和https有什么区别?”
....
??? 难道我每次请求数据的时候都要把这些默背一遍吗?这面试八股文呐,真真是让人头痛不已
别怕!为了让哥哥们能够一劳永逸,拒绝死记硬背!小弟我梳理了这份不怕忘的网络基础知识指南,供大家品尝~
什么是HTTP和TCP ?
首先,我们要知道这两个都是协议,完整的叫法是Http协议和TCP/IP协议
协议,就是双方约定的内容。比如我和你约定,我给你个苹果,你要给我香蕉。苹果换香蕉就是我们协议的具体内容
所以HTTP和TCP本质上没什么神秘的地方,只是对网络请求做了一些规范。
那么问题来了,既然都是协议,它们有什么不同呢?
具体的不同当然有很多。但如果不是专业的网络技术人员的话,只需要有个整体的了解即可。这时候就要搬出老师教我们的TCP/IP分层模型图。
嘻嘻,熟不熟悉?这里我们只需要记住应用层和传输层就可以了,其他的基本很少用到
从这个模型可以知道,网络请求是一个很复杂的过程,复杂到必须分好几层,每层把自己的任务完成好才可以请求成功
传输层的任务就是建立网络连接
应用层就是在建立好的网络连接上传递各种类型数据。比如文本,图像,视频等等
既然网络请求这么复杂,指望用一个协议来描述整个网络请求过程是不可能的
所以HTTP对应的就是应用层协议,TCP对应的是传输层协议
这就是HTTP和TCP的最大不同
Socket
这时候就引出一个概念,socket
什么是socket呢?
通过前文我们知道,HTTP和TCP只是协议而已,协议本身没有是实现功能的能力的,需要一个载体实现它。
socket就是tcp协议的实现。
它定义了一些建立连接的接口。比如connect,listen,read等等,这些接口方法的具体实现严格遵循TCP协议
好了,知道了是什么,接下来就是面试的重头戏
三次握手和四次挥手
我们首先明确,三次握手和四次挥手是TCP/IP协议的内容,它是属于运输层的,是网络请求在传输数据时建立连接和断开连接的方式
如何建立一个网络连接
在了解什么是三次握手之前,我们先探讨一个问题
现在有客户端client和服务端serve,我们怎么样建立一个网络连接?
最简单的当然是客户端向服务端发送一个建立连接的请求,然后爱管不管,我就当连接已经建立了,美滋滋的原地等待,等服务端给我发送数据
这样可以吗?
当然不行了兄弟
万一服务端压根就没开机,万一人家理都不理你呢
就像给妹妹写情书一样,妹妹回应你这事才有戏。你不管妹妹回不回应一个劲给人家写,还傻傻的在那等。
那不叫爱,那是X骚扰和备胎
所以我们得出建立连接的一个基本准则
“请求必须要有回应”
继续往下想。既然要有回应,那我客户端向你发个请求,等接收到服务端的回应,再发下个请求。依次进行,是不是显得非常有秩序?
不愧是你,这就是“停止等待协议”
超时重传
“停止等待”就是网络请求最简单的版本
简单就意味着问题,因为网络环境是不稳定的
比如客户端的每个请求都要等收到上个请求的回复才发送,如果上个请求因为网络波动延迟了,或者干脆丢掉了,那客户端的下个请求岂不是永远发不出去了?数据就卡在这里了?
为了解决这个问题,TCP协议里有个超时重传机制,如果长时间没收到回复就把原来的包再发一遍。还没收到再发,直到正常。
序列号
明白了网络连接建立时,“请求必须有回应”,“超时重传”,接下来我们再思考一个问题
我们知道,连接请求传输的数据是以数据包的形式传输的。也就是说,一次请求的数据是由多个数据包组成的。
如果一个数据包因为网络波动延迟了,在这延迟的期间触发了超时重传,这时候服务端就会接收到两个相同的包,服务端怎么处理呢?
处理的方法很简单。就是客户端在发送数据包的时候往里面加点“东西”,让服务端能够辨别这个包是从哪里来的
这个过程就是给数据包编号。这个号叫做数据包的序列号,这是接下来三次握手的关键
三次握手
终于到三次握手了,要不兄弟们先点个赞,换换脑子?
还是先上一个简单的前提
三次握手本质上其实是四次握手,只是把中间两次握手合并了而已。
因为建立连接是连续的。 服务端在第一次握手收到客户端的请求后,要马上发送回应, 同时发送自己的请求,所以把回应和请求合并成一次请求,也就是第二次握手
为什么不是两次握手而是三次握手呢?
那么问题来了,根据上面的“请求必须要有回应”基本准则
为什么不是两次握手而是三次握手呢?
谢希仁著的《计算机网络》第四版中,讲到 “三次握手” 的目的是 “为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。
这句话当做面试八股文背下来也没什么问题。但其实这里面跳过了一个关键原因
还记得我们说数据包为什么要有序列号吗?
是为了让服务端能够辨别数据包的来源,区分是否是过时的数据包。
我们把眼光从数据包上升到一次网络连接。如果一个数据包延迟比较久,久到这次连接断开,下次连接建立,这时候服务端收到了旧连接的包,如何区分这两次连接呢?
答案是再加一个序列号
这个序列号叫初始序列号,用来标识一个连接。
这样结论就很清晰了。
初始序列号用来标识是否是同一个连接,数据包序列号用来标识一次连接中数据包的来源。
所以客户端需要向服务端发送表示本次连接的初始序列号
慢着,你还是不懂为什么是三次握手不是两次?
哈呀,你忘了TCP协议是全双工通信吗?客户端和服务端的概念是相对的,性别互换,亲妈不爱
客户端给服务端发送初始序列号是客户端建立的连接,服务端同时也可以作为客户端,也要向对方发送建立连接的初始序列号。再加上之前说的握手合并,不就是三次握手了嘛
恍然大悟了吧? 嘿嘿
来,自我检查一下,把自己当成面试官问自己
“为什么是三次握手不是四次握手”
“为什么是三次握手不是两次握手”
四次挥手
漫漫长征走过了一半,接下来我们看断开连接的四次挥手
其实四次挥手和三次握手差不多,不同的是第二次和第三次挥手不能合并
这是为什么呢?
前面说三次握手能合并的原因是 「建立连接是连续的」,服务端收到第一次握手请求后要马上回应同时发送请求。但因为TCP是全双工通信,客户端断开连接后服务端可能还需要发送数据。
所以客户端一次“请求--回应”
只是断开了客户端-->服务端
的连接,服务端过一会后才发送请求断开服务端-->客户端
的连接
为什么要等待2MSL
这里有个小知识点,客户端在最后一次挥手发送回应后,会等待2msl(msl就是一个报文在网络上的最大存活时间)时间才完全关闭,这是为什么呢?
还是网络不稳定的问题。客户端最后一次挥手发出的回应报文如果延迟了或者丢了,服务端等待1个MSL没有收到的话会超时重传,重复第③次挥手的过程。
这样最多2MSL的时间客户端又会收到断开连接的请求,所以要最少等待2MSL时间再断开
好了,HTTP和TCP的大部分知识点就讲完了。当然可拓展的地方还有非常多,比如“超时重传”那里,为了解决性能问题又引入了连续传输,滑动窗口,拥塞控制等等。不过这些算HTTP知识的枝干,只要掌握主干知识,其余枝叶还不是手到擒来
当然面试官还会问一些简单记忆就可以回答的问题,比如:
“你来说说Http1.0 Http1.1和Http2.0的区别”
Http1.0,Http1.1和Http2.0的区别
刚才我们说的其实都是Http1.0的内容,用脚指头想Http1.1和2.0一定是做了优化。
Http1.1的优化主要是实现了 长连接 ,同时也是目前最广泛的Http协议。
长连接的意思很简单。在Http1.0中,我们每请求一张图片就要建立一次Tcp连接,请求一个网页往往有几十上百次Tcp建立连接,断开连接,这样非常耗时,长连接的意思就是多个请求可以复用一个Tcp连接,提高了Tcp连接的利用率
如果面试官问你还有呢,你就跟他说还有断点续传
这个很容易理解吧,在Http1.0中,我们想知道一段视频中间的数据,必须先把整个视频下载下来。Http1.1优化了这个逗比的场景,在请求头中加入了range,可以只请求数据的一部分
如果问你还有呢....
你就说常用的差不多就这些了,不行我回去好好看看,等我们做了同事我再跟你好好说..
至于Http2.0就更牛逼了
它支持多路复用。 之前讲Http1.1只是复用Tcp连接,Http2.0可以在一个请求上请求多个资源
类似于把两个请求合并成一个请求。服务端一次返回两次请求的资源。Amazing
未完待续
不知不觉就写了这么多了。尽可能通俗地把知识讲出来,是为了能给大家的理解起到一点点小小的帮助,不用每次痛苦地背八股文。
作者:方木Rudy
链接:https://juejin.cn/post/6935611048862941220
来源:掘金