计算机网络

TCP/IP模型

image-20220408153900742

TCP/IP协议族按照层次由上到下,层层包装。

第一层是应用层,这里面有http,ftp,等等我们熟悉的协议。

第二层是传输层,著名的TCP和UDP协议就在这个层次。

第三层是网络层,IP协议就在这里,它负责对数据加上IP地址和其他的数据以确定传输的目标。

第四层是数据链路层,这个层次为待传送的数据加入一个以太网协议头,并进行CRC编码,为最后的数据传输做准备。

image-20220408154044966

TCP/IP协议通信的过程其实就对应着数据入栈与出栈的过程。入栈的过程,数据发送方每层不断地封装首部与尾部,添加一些传输的信息,确保能传输到目的地。出栈的过程,数据接收方每层不断地拆除首部与尾部,得到最终传输的数据。

IP协议是TCP/IP协议的核心,所有的TCP,UDP,ICMP,IGCP的数据都以IP数据格式传输。要注意的是,IP不是可靠的协议,这是说,IP协议没有提供一种数据未传达以后的处理机制,这被认为是上层协议——TCP或UDP要做的事情。

IP地址

在数据链路层中我们一般通过MAC地址来识别不同的节点,而在IP层我们也要有一个类似的地址标识,这就是IP地址。
32位IP地址分为网络位和地址位,这样做可以减少路由器中路由表记录的数目,有了网络地址,就可以限定拥有相同网络地址的终端都在同一个范围内,那么路由表只需要维护一条这个网络地址的方向,就可以找到相应的这些终端了。
A类IP地址:1.0.0.0127.0.0.0
B类IP地址:128.0.0.0
191.255.255.255
C类IP地址:192.0.0.0~223.255.255.255

ARP及RARP协议

ARP协议完成了IP地址与物理地址的映射(地址解析协议)。每一个主机都设有一个 ARP 高速缓存,里面有所在的局域网上的各主机和路由器的 IP 地址到硬件地址的映射表。当源主机要发送IP包到目的主机时,会先检查自己的ARP高速缓存中有没有目的主机的MAC地址,如果有,就直接将数据包发到这个MAC地址,如果没有,就向所在的局域网发起一个ARP请求的广播包(在发送自己的 ARP 请求时,同时会带上自己的 IP 地址到硬件地址的映射),收到请求的主机检查自己的IP地址和目的主机的IP地址是否一致,如果一致,则先保存源主机的映射到自己的ARP缓存,然后给源主机发送一个包含自己的MAC地址的ARP包。源主机收到响应数据包之后,先添加目的主机的IP地址与MAC地址的映射,再进行数据传送。如果源主机一直没有收到响应,表示ARP查询失败。

RARP协议的工作与此相反。完成了物理地址到IP地址的映射

ICMP协议

IP协议并不是一个可靠的协议,它不保证数据被送达,那么,自然的,保证数据送达的工作应该由其他的模块来完成。其中一个重要的模块就是ICMP(网络控制报文)协议。ICMP不是高层协议,而是IP层的协议当传送IP数据包发生错误。比如主机不可达,路由不可达等等,ICMP协议将会把错误信息封包,然后传送回给主机。给主机一个处理错误的机会,这也就是为什么说建立在IP层以上的协议是可能做到安全的原因。

ping

ping可以说是ICMP的最著名的应用,是TCP/IP协议的一部分。利用“ping”命令可以检查网络是否连通,可以很好地帮助我们分析和判定网络故障。

当我们某一个网站上不去的时候。通常会ping一下这个网站。ping会回显出一些有用的信息。

它利用ICMP协议包来侦测另一个主机是否可达原理是用类型码为0的ICMP发请求,受到请求的主机则用类型码为8的ICMP回应

Traceroute

Traceroute是用来侦测主机到目的主机之间所经路由情况的重要工具

Traceroute的原理非常非常有意思。它收到到目的主机的IP后,首先给目的主机发送一个TTL=1(Time To Live)的UDP数据包,而经过的第一个路由器收到这个数据包以后,就自动把TTL减1,而TTL变为0以后,路由器就把这个包给抛弃了,并同时产生一个主机不可达的ICMP数据报给主机。主机收到这个数据报以后再发一个TTL=2的UDP数据报给目的主机,然后刺激第二个路由器给主机发ICMP数据报。如此往复直到到达目的主机。这样,traceroute就拿到了所有的路由器IP。

TCP/UDP

image-20220408160013259

image-20220408160231002

什么是三次握手?

TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换 TCP窗口大小信息。

image-20220408161526139

序列号:Sequence Number。确认号:ACK置位。

第一次握手:建立连接。客户端发送连接请求报文段,将SYN(标志位) 位置为1,Sequence Number(发送序号)为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;

第二次握手:服务端收到客户端的SYN报文后,根据SYN置位可知客户端在请求建立连接。然后服务端发送一个SYN置位,ACK置位,确认号为客户端初始序列号+1,序列号为随机生成的服务端初始序列号 的报文给客户端。随后服务端进入SYN_RCVD状态。

第三次握手:客户端根据报文的SYN标志位被置位可知服务端同意建立请求。客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y + 1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。

TCP建立连接可以两次握手吗?为什么?(为什么要三次握手)

不可以,有两个原因。

  1. 第一个,是当一个因超时等原因已经失效的连接请求报文段传送到了Server。本来这是已失效的报文段,但Server会认为这是Client再次发出的新的连接请求,于是就向Client发出ACK报文段同意请求。由于是两次握手,新的连接在服务端看来已经建立了,Server会一直维持连接等待Client发送数据,白白浪费资源。
  2. 第二个是,只有两次握手的话,Server无法确认Client正确接收到了第二次握手的报文也就无法保证Client和Server之间成功交换了初始序列号。
可以采用四次握手吗?为什么?

可以。但是会降低传输效率。

四次握手是指:将第二次握手的报文段拆分成ACK报文和SYN报文。出于优化的目的,这是可以合并的。

第三次握手中,如果客户端的ACK报文未送达服务端,会怎么样?

Server:由于Server没有收到ACK确认报文,因此会重发之前SYN+ACK报文(默认重发5次,之后自动关闭连接,进入CLOSED状态),Client收到SYN+ACK报文后会重发ACK报文。

Client端有两种情况。

  1. 一种是Server超时重发过程中,Client端向服务端发送了包含ACK标志位的数据报文,服务端读取确认号后,根据确认号大于服务端初始序列号+1,可以进入ESTABLISHED状态。
  2. 另一种情况是,Server已经进入CLOSED状态了,Client向服务端发送数据,服务端会以RST包应答。
初始序列号是什么?(序列号的作用是什么?)

TCP是一种全双工的连接,它在两个方向都有一个初始序列号。在同一个方向上,发送端会以初始序列号作为原点,对要传输的数据进行编号。接收端通过序列号可以确认数据是否合法,同时发送端根据接收端发送的ACK报文中的确认号可以确认哪些数据已被接收。

什么是四次挥手?

当客户端和服务器通过三次握手建立了TCP连接以后,当数据传送完毕,肯定是要断开TCP连接的啊。那对于TCP的断开连接,这里就有了神秘的“四次分手”。

image-20220408165305357

  • 第一次挥手:Client发送一个FIN置位,并有相应序列号的报文给Server,随后进入FIN_WAIT_1状态。此时,Client不再发送数据,但仍可以接收数据。
  • 第二次挥手:Server收到FIN后,发送一个ACK置位,确认号为收到序列号+1的报文,进入CLOSE_WAIT状态。Client接收到ACK报文后,进入FIN_WAIT_2状态。表示同意断开连接请求
  • 第三次挥手:Server发送一个FIN置位,并填写了对应序列号的报文给Client,随后进入LAST_ACK状态。请求关闭连接。
  • 第四次挥手:Client收到服务器的FIN报文后,进入TIME_WAIT状态;接着发送一个ACK置位,确认号为三次挥手的序列号+1的报文给Server;Server接收到后,确认ACK标志位和确认号后,进入CLOSED状态客户端等待2*MSL(报文段最长寿命)时间后,也进入CLOSED状态。
为什么不能把服务端发送的ACK和FIN合并,变成三次挥手?(CLOSE_WAIT状态的意义是什么?)

因为服务器收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复ACK,表示接收到了断开连接的请求。等到数据发完之后再发FIN,断开服务器到客户端的数据传送。

客户端TIME_WAIT状态的意义是什么?

第四次挥手时,客户端发送给服务器的ACK有可能丢失,TIME_WAIT状态就是用来重发可能丢失的ACK报文如果Server没有收到ACK,就会重发FIN,如果Client在2MSL的时间内收到了FIN,就会重新发送ACK并再次等待2MSL,防止Server没有收到ACK而不断重发FIN。

TCP流量控制

如果发送方把数据发送得过快,接收方可能会来不及接收,这就会造成数据的丢失。所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。
利用滑动窗口机制实现对发送方的流量控制。

接收端会维护一个接收窗口,根据自身剩余缓冲区大小动态调整,在返回ACK报文时将接收窗口大小放在TCP报文首部的窗口字段中告知发送端。发送窗口的大小不能超过接收窗口的大小,只有当发送端发送的数据收到确认后,才能右移发送窗口。

发送窗口的上限为接受窗口和拥塞窗口中的较小值。接受窗口表明了接收方的接收能力,拥塞窗口表明了网络的传送能力。

什么是零窗口?(接收窗口为0时会怎么样?)

如果接收方没有能力接收数据,就会将接收窗口设置为0,这时发送方必须暂停发送数据,但是会启动一个持续计时器(persistence timer),到期后发送一个大小为1字节的探测数据包,以查看接收窗口状态。如果接收方能够接收数据,就会在返回的报文中更新接收窗口大小,恢复数据传送。

TCP的拥塞控制是怎么实现的?

发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去。但只要网络出现拥塞,拥塞窗口就减小一些,以减少注入到网络中的分组数。

拥塞控制主要由四个算法组成:慢启动拥塞避免快速重传快速恢复

  1. 慢启动: 在刚建立TCP连接或者出现丢包的时候,发送端处于慢启动状态,这个时候会把拥塞窗口设置为1个MSS。每接收到一个ACK报文,就增加1个MSS(Maximum Segment Size,最大报文长度)。这样每经过一个RTT,拥塞窗口的大小就会加倍。

  2. 拥塞避免: 当拥塞窗口的大小达到慢启动阈值(ssthresh)时,开始执行拥塞避免算法。每经过1个RTT,拥塞窗口大小不再指数增长,而是线性增长。

  3. 快速重传:

    接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不是等到自己发送数据时捎带确认。

    发送方只要一连收到三个重复确认就立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。

  4. 快速恢复:

    当发送方连续收到三个重复确认时,就把慢启动阈值减半,同时将拥塞窗口的大小置为慢启动阈值的大小,然后执行拥塞避免算法。

    不执行慢开始算法的原因是:因为如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方认为现在网络可能没有出现拥塞。

TCP如何保证可靠性?
  1. TCP首部的校验和
  2. 应答机制:接收端收到数据之后会根据序列号,会发送一个ACK确认报文。
  3. 超时重发机制:发送端发出数据后,会启动一个定时器,超时未收到ACK报文,就会重发。
  4. 流量控制:确保接收端能完整接收发送端的数据而不会缓冲区溢出。
  5. 拥塞控制:当网络拥塞时,通过拥塞控制减少数据的发送,防止包丢失。
TCP与UDP的区别
  1. TCP是面向连接的,UDP是无连接的。

  2. TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多。

  3. TCP是面向字节流的,UDP是面向报文的。

    面向字节流是指发送数据时以字节为单位,一个数据包可以拆分成若干组进行发送,而UDP一个报文只能一次发完。

  4. TCP有拥塞控制机制,而UDP没有,网络出现的拥塞不会使源主机的发送速率降低,这对某些实时应用是很重要的,比如媒体通信,游戏。

  5. TCP首部开销(20字节)比UDP首部开销(8字节)要大。

  6. UDP 的主机不需要维持复杂的连接状态表。

Http和Https

HTTP请求报文

image-20220408172758787

一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成

请求行分为三个部分:请求方法、请求地址和协议版本

请求头部为请求报文添加了一些附加信息,由“名/值”对组成,每行一对,名和值之间使用冒号分隔。

请求头部的最后会有一个空行,表示请求头部结束,接下来为请求数据,这一行非常重要,必不可少。

请求数据为可选部分,比如GET请求就没有请求数据。

HTTP响应报文

image-20220408172749188

HTTP响应报文主要由状态行、响应头部、空行以及响应数据组成。

状态行:由3部分组成,分别为:协议版本,状态码,状态码描述。

响应头部:与请求头部类似,为响应报文添加了一些附加信息

响应数据:用于存放需要返回给客户端的数据信息。

HTTP和HTTPS有什么区别?
  1. 知名端口不同:HTTP的知名端口是80,HTTPS是443。
  2. HTTP是明文传输,HTTPS运行在SSL之上,添加了加密和认证机制,更加安全。
  3. HTTPS由于需要加密和解密,对主机会有更大的CPU和内存开销,同时传输开销也更大。
  4. HTTPS通信需要证书,一般要向证书颁发机构(CA)购买。
HTTPS的连接过程?(HTTPS的加密过程?)
  1. 客户端向服务器发送请求,同时发送客户端支持的一套加密规则(包括对称加密、非对称加密、摘要算法);
  2. 服务器从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥(用于非对称加密,用证书机构的私钥加密后的服务器公钥),以及证书的颁发机构等信息(证书中的私钥只能用于服务器端进行解密);
  3. 客户端验证服务器的合法性,包括:证书是否过期,CA 是否可靠,证书机构的公钥能否正确解开服务器证书的“数字签名”,服务器证书上的域名是否和服务器的实际域名相匹配;
  4. 如果证书受信任,或者用户接收了不受信任的证书,浏览器会生成一个随机密钥(用于对称算法),并用服务器提供的公钥加密(采用非对称算法对密钥加密);使用Hash算法对握手消息进行摘要计算,并对摘要使用之前产生的密钥加密(对称算法);将加密后的随机密钥和摘要一起发送给服务器;
  5. 服务器使用自己的私钥解密,得到对称加密的密钥,用这个密钥解密出Hash摘要值,并验证握手消息是否一致;如果一致,服务器使用对称加密的密钥加密握手消息摘要发给浏览器;
  6. 浏览器解密并验证摘要,若一致,则握手结束。之后的数据传送都使用对称加密的密钥进行加密。
什么是对称加密、非对称加密?区别是什么?
  • 对称加密:加密和解密使用相同的密钥。
  • 非对称加密:有两个密钥:公钥和私钥。用公钥加密的,需要用私钥解密。用私钥加密的,需要用公钥解密。
  • 区别:对称加密速度更快,通常用于大量数据的加密;非对称加密安全性更高,原因是不需要传输私钥。
数字签名的原理

证书机构用私钥进行签名,客户端用公钥验证签名。因为我们信任证书机构,且除证书机构外没有人持有该私钥,客户端的公钥嵌入在了浏览器中,所以保证了数字签名的可靠。

GET和POST的区别?
  1. GET方法是幂等的,即访问同一个资源,总是得到相同的数据。
  2. 请求形式上:GET请求的参数附在URL之后,POST请求的参数在请求体中。
  3. GET请求可被缓冲、收藏、保留到历史记录,且其请求数据明文出现在URL中。POST的参数不会被保存,安全性相对较高。
  4. GET只允许ASCII字符(因为URL只支持ASCII字符),POST则没有限制。
  5. GET的长度有限制(操作系统或者浏览器),而POST数据大小无限制。
Session与Cookie的区别?

Session是服务器端保持状态的方案,Cookie是客户端保持状态的方案。

Cookie保存在客户端本地,客户端请求服务器时会将Cookie一起提交;Session保存在服务端,通过检索Session id查看状态。保存Session id的方式可以采用Cookie,如果禁用了Cookie,可以使用URL重写机制(把会话ID保存在URL中)。

从输入网址到获得页面的过程?

  1. 浏览器根据输入URL中的域名查询DNS,获取对应的IP地址:具体过程是浏览器查询自身的DNS缓存,未命中则查询操作系统的DNS缓存,未命中则向本地DNS服务器进行查询。本地DNS服务器收到请求,如果没有缓存,就向根域名服务器请求,根域名服务器会返回相应的顶级域名服务器地址;然后向顶级域名服务器请求,会返回名称服务器地址;然后向名称服务器请求,就能得到IP地址了。
  2. 浏览器获得域名对应的IP地址以后,就会向服务器请求建立TCP连接,也就是发起TCP三次握手。
  3. TCP连接建立完成后,浏览器向服务器发送HTTP请求。
  4. 服务器接收到请求后,将处理结果及相应的视图返回给浏览器。
  5. 浏览器解析并渲染视图,若遇到对js文件、css文件及图片等静态资源的引用,则继续向服务器请求这些资源。
  6. 最后浏览器根据请求获取到的资源、数据渲染页面,向用户呈现一个完整的页面。