TCP/IP四层模型: 数据链路层,网络层,传输层,应用层
OSI七层模型:物理层,数据链路层,网络层,传输层,表示层,会话层,应用层
TCP/IP四层模型
物理层
通过光缆,网线实现电脑与电脑之间的连接,传输电信号(0/1)。
数据链路层
MAC地址。(48位二进制 -> 12个16进制)
交换机。
定义电路信号如何分组。以太网协议。
以太网规定:每台电脑有一个网卡,每个网卡必须包含一个mac地址,mac地址就是这个网卡的唯一标识。
在传输数据包的时候,必须指定接收者的mac地址才能传输数据。
传输数据不是精准推送,以太网里面,如果一个电脑发个数据包出去,会广播给局域网内的所有电脑设备的网卡,然后每台电脑都从数据包里获取接收者的mac地址,跟自己的mac地址对比一下,如果一样,就说明这是发给自己的数据包。
广播方式仅仅针对一个子网(局域网)内的电脑,会广播。如果需要传输数据至其他局域网的电脑,就需要用到网络层。
网络层
IP地址。(32位二进制 -> 4个十进制)
路由器。
IP地址与子网掩码的与运算,比较网络部分的地址是否一致,一致则说明是在同一个子网内,否则不在同一个子网内。
有了网络层的ip地址后,两台在子网内的电脑就可以通过广播+mac地址判断来传输数据包进行通信了。
但是如果发现接受的数据包的计算机不在子网内,就不能通过广播来发送数据包,需要通过路由来发送数据包。路由器(其实就是配置了多个网卡的一个专用设备,通过不同的网卡接入不同的网络),发送方先传输数据至网关,通过路由器路由至其他子网的网关,其他网关再进行广播,可能直接找到接收方或到下一个网关再进行转发。
交换机:通过mac地址来寻址和传输数据包。主要用在局域网通信。
路由器:通过ip地址寻址和传输数据包。
两个局域网的电脑如何通信
局域网1的电脑,要发送数据到局域网2的电脑,再数据包里写上自己的IP地址和对方的IP地址,但是他们俩不在一个局域网内,于是局域网1内的电脑,先通过交换机将数据包发送给路由器,这个过程需要将路由器的一块网卡的IP地址对应的mac地址写到数据包的头部,然后才能通过交换机广播出去,路由器接收到之后比较自己的一块网卡的mac地址,就知道是来找自己的。
接着路由器接收到数据包之后,就会在局域网2内,将目标机器的ip地址对应的mac地址写入至数据包头部,然后通过交换机进行广播通知,发送到局域网内的电脑。
如何知道IP地址和MAC地址的对应关系
ARP协议。
一个局域网内让各个设备都知道每个设备的ip地址和mac地址的对应关系。
一般是某个机器发送广播通知自己的ip地址和mac地址的对应关系,让你后每个机器给他一个回应。
传输层
TCP协议,UDP协议。
一台机器,是很多程序用一个网卡进行网络通信的,比如浏览器,QQ,视频直播,这些软件都共用一个网卡往外面发送数据和接收数据。
所以需要一个端口号来监听应用程序,通过监听端口号来提取发送到该端口的数据。
端口号: 0~65536, 0~1023被系统占用。
网络层是基于IP地址,进行主机与主机的寻址和通信。传输层,是建立某个主机的某个端口,到另外一台主机的某个端口的连接和通信。
应用层
负责解释数据。 如收到邮件如何处理,收到网页如何处理。
HTTP协议,FTP协议。
针对不同的应用,邮件,网页,都是定义了不同的应用层协议。
图解四层模型
每一层的装包信息(请求头与请求体)
http请求报文
比如
GET http://172.194.26.108/test HTTP/1.1
Host: **
User-Agent: **
请求体:比如常见的可以放一个json就构成一个http请求报文。
浏览器请求一个地址,先按照应用层的http协议,封装一个应用层数据包,数据包里面存放了http请求报文。这个时候会将这个http请求报文打包成一个数据包,仅仅只是数据包的数据部分,此时数据包没有头的。(应用层)。
接着跑到传输层,tcp协议会让你设置端口,发送方的端口随机选一个,接收方端口一般是默认80端口。这个时候,会把应用层数据包封装到tcp数据包中去,而且加个tcp头,tcp头放了端口信息。(传输层)
接着跑到网络层,走IP协议,将tcp数据包和tcp头放在ip数据包里,然后搞个IP头,存放本机和目标主机的IP地址信息。(网络层)
接着跑到数据链路层,走以太网协议。将ip数据包和ip头放在以太网数据包里,然后搞个以太网头,放入本机网卡的mac地址和目标主机的mac地址(如果不是同一个子网的,放的是本机网卡mac地址和网关的网卡的mac地址)。(传输层)
以太网数据包限制是1500字节。但是假设这个时候,IP数据包都有5000字节了,那么需要对IP数据包进行分片。
这4个以太网数据包会通过交换机发到网关上,然后路由器是通过连通别的子网,通过多个网关转发,跑到目标主机,目标主机接收到4个以太网数据包。然后目标主机通过ip头的序号,拼接数据包,还原完整的ip数据包。接着从ip数据包里面拿出tcp数据包,再从tcp数据包里取出http数据包,读取http数据包里的各种协议内容,做一些处理。然后把响应结果封装成http响应报文,封装再http数据包里,再一样的过程,封装tcp数据包,封装ip数据包,封装以太网数据包,接着通过网关给发回去。
网络通信的数据传输流程
TCP三次握手
手绘TCP三次握手流程图
为啥是三次握手,不是两次握手或者四次握手
两次握手的弊端:
(1)如果客户端在第一次握手的时候,因为网络延迟或者其他故障问题导致第一次握手被卡住,服务端未收到第一次握手请求,自然也不会发起第二次的握手请求。
(2)此时客户端会重新发起第一次握手请求,此时服务端收到了请求,也给客户端发送了第二次握手,然后两次握手后,就建立的连接,服务端也开辟了资源等待客户端来请求。后面请求结束后,tcp连接也关闭。
(3)但是尴尬的是,之前因为网络延迟导致卡住的第一次握手,后面终于发到了服务器,服务器接收了握手请求之后,直接开辟了资源准备客户端发送数据,并发起了第二次握手请求。如果此时没有第三次握手请求的话,就会导致服务器开辟的资源一直在等待着客户端来使用,但是客户端其实并不需要再请求服务端资源了。
所以,如果只是两次握手请求的话,就可能会出现上面类似的情况。
为什么不是四次握手
三次握手能解决的事情,为什么要四次握手去浪费资源。
TCP断开连接四次挥手
(1)第一次挥手,客户端发送报文,FIN=1,seq=u,此时进入FIN-WAIT-1状态。
(2)第二次挥手,服务端收到报文,此时进入CLOSE_WAIT状态,返回一个报文,ACK=1,ack=u+1,seq=v。客户端收到这个报文之后,直接进入FIN-WAIT-2状态,此时客户端到服务端的连接就释放了。
(3)第三次挥手,服务端发送连接释放报文,FIN=1,ack=u+1,seq=w,服务端进入LAST-ACK状态。
(4)第四次挥手,客户端收到连接释放报文之后,发应答报文,ACK=1,ack=w+1,seq=u+1,进入TIME_WAIT状态,等待一会客户端进入CLOSED状态,服务端收到报文之后就进入CLOSED状态。
为什么是四次挥手
(1)客户端发起释放连接的请求时,服务端接收到请求之后,可能还会有资源数据未发完至客户端,所以此时服务端在第二次挥手的时候,就给客户端发送应答报文,告知客户端服务端知道你要释放连接了,等我这边资源发送完毕之后,我会去释放连接的。
(2)接着等到服务端资源发送完毕之后,服务端就会向客户端发起第三次挥手请求,说明可以释放连接了,此时客户端收到服务端的释放请求之后,就会发送一个应答报文,告知服务端收到服务端释放连接的请求了。然后客户端和服务端就都会在一段时间内进入CLOSED状态。
TCP其他相关面试题
为什么TIME_WAIT状态需要经过2MSL(最大报文生存时间)才会返回到CLOSE状态?
因为网络传输不可靠,在发送方发送ack包确认服务端的关闭请求时可能会造成丢失。用TIME_WAIT状态就是用来重发可能丢失的ACK包。
在客户端发送ack包时存在丢失,服务端没有收到ack包,将不断重复发送FIN片段。所以客户端不能立即关闭,它必须确定服务端接收到了该ACK包。
2MSL:一个报文的最大生存时间是MSL,2MSL就是一个发送和一个回复的最大时间。如果直到2MSL,客户端都没有接收到服务端重发的FIN包,那么客户端可以确定发送的ACK包已经被服务端所接收。则结束TCP连接。
如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP设有一个保活计时器。客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端请求后都会重新复位这个计时器,时间通常是设置为2个小时,若两小时没有收到客户端的任何数据,服务端就会发送一个探测报文段,以后每隔75分钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
为什么TCP三次握手,为什么需要在发送一次握手确认?
主要防止已经失效的连接请求报文突然又传到了服务器,从而产生错误。
如果使用的是两次握手建立连接,会有这样的场景。客户端发送了一个请求连接并且丢失,只是因为在网络结点中滞留的时间太长了,由于TCP客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,关闭连接。此时此前滞留的那一次请求连接,在网络通畅后到达了服务器,这个报文本该失效,但是,两次握手的机制将会让客户端和服务端再次建立连接,这将导致不必要的错误和资源的浪费。
如果采用三次握手,就算那一次的失效报文传送过来,服务端接收到了那条失效报文并且回复了确认报文,但是客户端不会再次发送确认,由于服务器收不到确认,就知道客户端并没有请求连接。
HTTP协议工作原理
http1.0 短连接
互联网初期,一般网页几乎没有什么图片,就挂了一大段文字。
http1.0要指定keep-alive来开启持久连接,默认是短连接。就是浏览器每次请求都要重新建立一次tcp连接,请求结束之后就会释放tcp连接。
http1.1 长连接
目前网页丰富,会加载大量的图片,css,js等。此时如果每次请求,都需要建立一次tcp连接,那就是非常耗费资源和时间的。所以此时就会只建立一次tcp连接,并让这个链接一直保持着,不会立马断开,之后加载图片,css,js之类的请求,都会基于这个tcp连接来请求。最后过一段时间,等到事情结束,才会去释放一个tcp连接。大幅度提升打开复杂网页的速度和性能。
http1.1还支持host头,也就是可以支持虚拟主机。而且对断点续传有支持。
http2.0 多路复用
基于一个tcp连接并行发送多个请求以及接收响应,解决了http1.1对同一时间同一域名的请求有限制的问题。
二进制分帧,将传输数据包拆分为更小的帧(数据包),提高性能,实现低延迟高吞吐。
HTTP长连接工作原理
http本身没有什么所谓的长连接短连接。其实说白了都是http下层的tcp连接是长连接还是短连接。
tcp连接保持长连接,那么多个http请求和响应都可以通过一个连接来走。
http1.1默认是走长连接,底层都是一个网页一个tcp连接,一个网页的所有图片,css,js的资源加载,都走底层的tcp连接来多次http请求。
http1.0底层的tcp是短连接,一个网页发起请求,每个请求都是先tcp三次握手,然后发送请求,获取响应,然后tcp四次挥手断开连接。每个请求,都会先连接后断开。