计网知识点与面试题汇总
一.网络分层模型
1. 五层模型(综合OSI和TCP/IP的优点)
- 应用层:为应用程序提供交互服务。在互联网中的应用层协议很多,如域名系统DNS、HTTP协议、SMTP协议等
- 传输层:负责向两台主机进程之间的通信提供数据传输服务。传输层的协议主要有传输控制协议TCP和用户数据协议UDP
- 网络层:选择合适的路由和交换结点,确保数据及时传送。主要包括IP协议,网络层提供主机到主机的数据通信服务
- 数据链路层:数据链路层将网络层交下来的 IP 数据报组装成帧,在两个相邻节点间的链路上传送帧,主要功能链路管理、差错检验、封装成帧、透明传输
- 物理层:实现相邻节点间比特流的透明传输,尽可能屏蔽传输介质和物理设备的差异
2. ISO七层模型
应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
表示层:数据的表示、安全、压缩,确保一个系统的应用层所发送的信息可以被另一个系统的应用层读取
会话层:建立、管理、终止会话,对应主机进程,指本地主机与远程主机正在进行的会话
3. TCP/IP四层模型
- 应用层(参考OSI模型上三层)
- 传输层(对应OSI的传输层)
- 网际IP层(对应于OSI参考模型的网络层 )
- 网络接口层(与OSI参考模型的数据链路层、物理层对应 )
二.UDP协议
1. UDP的主要特点
- UDP是无连接的,发送数据不需要建立连接,减少了开销和发送数据的延迟
- UDP尽最大努力交付,无需维护复杂的网络状态
- UDP面向报文,拆分任务交给网络层
- UDP无拥塞控制,源主机发送速率保存恒定,适合实时会议、电话等
- UDP支持一对一、一对多、多对一、多对多交互通信
- UDP首部开销少,8字节,TCP20字节
2. UDP首部
UDP的首部只有8个字节,每个字段两个字节
- 源端口:源端口号,需要对方回信时需要,不需要全0
- 目的端口:目的端口号
- 长度:UDP用户报长度,最小为8(只有首部)
- 校验和:判断UDP用户数据报是否有错,有错则丢弃
如果接收方发现收到的报文的端口号不对,则丢弃报文,并由网际控制报文协议ICMP发送端口不可达差错报文给发送方
3. UDP伪首部
计算校验和时添加的,共12字节,并不向上或向下传递
- 源IP:4字节
- 目的IP:4字节
- 全0:1字节
- 全1:1字节
- UDP长度:2字节
校验和计算过程
- 全0放入检验和字段,UDP数据字段填0至数据字段为偶数个字节
- 按二级制反码运算求和
- 求刚刚得出的结果的补码
三.TCP协议
1. TCP的主要特点
- 面向连接,在传输数据前必须建立连接,在数据传输后必须释放连接
- TCP只支持点到点数据传输
- TCP提供可靠交付的服务,保证数据无差错、不丢失、不重复并按序达到
- TCP提供全双工通信,通信双方在建立连接后任何时间都可发送数据,TCP各端都设有发送缓存与接收缓存
- 面向字节流,“流”是指流入进程与流出进程的字节序列,面向字节流的含义是,虽然应用程序与TCP交互的是一个一个数据块,但TCP仅仅把应用程序交下来的数据看出一串无结构、有序的字节流
2. TCP首部
TCP首部长度前20字节是固定的,,后面4n个字节根据需要而增加的,最大60字节
- 源端口、目的端口各两字节
- 序号:4字节,在一个TCP连接中传送的字节流的每一个字节都按顺序编号,该字段表名该报文数据起始的位置
- 确认号:4字节,期望收到对方下一个报文的第一个数据字节的序号
- 数据偏移:4位,表明首部长度,单位是4字节
- 保留:6位,目前为0
- 紧急URG:URG=1有效,与紧急指针配合使用
- 确认ACK:ACK=1才有效,TCP规定,在建立连接后的所有传送的报文段必须把ACK置为1
- 推送PSH:PSH=1,接收方尽快交付给应用进程,不用等到整个缓存满了再交付
- 复位RST:RST=1,TCP连接出去严重错误,必须释放连接
- 同步SYN:用来建立连接的同步序号
- 终止FIN:用来释放连接
- 窗口:2字节,接收方让发送方设置其发送窗口的依据
- 校验和:2字节
- 紧急指针:2字节
- 选项:最长40字节
3. 滑动窗口协议
TCP 利用滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,保证接收方来得及接收。 TCP会话的双方都各自维护一个发送窗口和一个接收窗口。接收窗口大小取决于应用、系统、硬件的限制。发送窗口则取决于对端通告的接收窗口。接收方发送的确认报文中的window字段与序列号字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将接收方的确认报文window字段设置为 0,则发送方不能发送数据。
TCP头包含window字段,16bit位,它代表的是窗口的字节容量,最大为65535。这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。接收窗口的大小是约等于发送窗口的大小。
4. TCP拥塞控制
TCP拥塞控制主要为了防止过多的数据注入到网络中。 几种拥塞控制方法:慢开始( slow-start )、拥塞避免( congestion avoidance )、快重传( fast retransmit )和快恢复( fast recovery )
- 慢开始:把拥塞窗口 cwnd 设置为一个最大报文段MSS的数值。而在每收到一个对新的报文段的确认后,把拥塞窗口增加至多一个MSS的数值。每经过一个传输轮次,拥塞窗口 cwnd 就加倍。 为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量。
当 cwnd < ssthresh 时,使用慢开始算法。
当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞控制避免算法。 - 拥塞避免:让拥塞窗口cwnd缓慢地增大,每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口cwnd按线性规律缓慢增长。
无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送 方窗口值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生 拥塞的路由器有足够时间把队列中积压的分组处理完毕。 - 快重传
有时个别报文段会在网络中丢失,但实际上网络并未发生拥塞。如果发送方迟迟收不到确认,就会产生超时,就会误认为网络发生了拥塞。这就导致发送方错误地启动慢开始,把拥塞窗口cwnd又设置为1,因而降低了传输效率。
快重传算法可以避免这个问题。快重传算法首先要求接收方每收到一个失序的报文段后就立即发出重复确认,使发送方及早知道有报文段没有到达对方。
发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待重传计时器到期。由于发送方尽早重传未被确认的报文段,因此采用快重传后可以使整个网络吞吐量提高约20%。 - 快恢复
当发送方连续收到三个重复确认,就会把慢开始门限ssthresh减半,接着把cwnd值设置为慢开始门限ssthresh减半后的数值,然后开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大。
在采用快恢复算法时,慢开始算法只是在TCP连接建立时和网络出现超时时才使用。 采用这样的拥塞控制方法使得TCP的性能有明显的改进。
5. TCP粘包拆包
TCP是面向流,没有界限的一串数据。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。
为什么会产生粘包和拆包呢?
- 要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包;
- 接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包;
- 要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包;
- 待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。即TCP报文长度-TCP头部长度>MSS。
解决方案:
- 发送端将每个数据包封装为固定长度
- 在数据尾部增加特殊字符进行分割
- 将数据分为两部分,一部分是头部,一部分是内容体;其中头部结构大小固定,且有一个字段声明内容体的大小。
6. TCP三次握手
- 第一次握手:客户端向服务端发起建立连接请求,客户端会随机生成一个起始序列号x,客户端向服务端发送的字段中包含标志位SYN=1,序列号seq=x,ACK=0。第一次握手前客户端的状态为CLOSE,第一次握手后客户端的状态为SYN-SENT(同步已发送)。此时服务端的状态为LISTEN。
- 第二次握手:服务端在收到客户端发来的报文后,会随机生成一个服务端的起始序列号y,然后给客户端回复一段报文,其中包括标志位SYN=1,ACK=1,序列号seq=y,确认号ack=x+1。第二次握手前服务端的状态为LISTEN,第二次握手后服务端的状态为SYN-RCVD(同步已送达),此时客户端的状态为SYN-SENT。(其中SYN=1表示要和客户端建立一个连接,ACK=1表示确认序号有效)
- 第三次握手:客户端收到服务端发来的报文后,会再向服务端发送报文,其中包含标志位ACK=1,序列号seq=x+1,确认号ack=y+1。第三次握手前客户端的状态为SYN-SENT,第三次握手后客户端和服务端的状态都为ESTABLISHED。此时连接建立完成。
第三次确认需要的原因:第三次握手主要为了防止已失效的连接请求报文段突然又传输到了服务端,导致产生问题。比如客户端A发出连接请求,可能因为网络阻塞原因,A没有收到确认报文,于是A再重传一次连接请求。连接成功,等待数据传输完毕后,就释放了连接。然后A发出的第一个连接请求等到连接释放以后的某个时间才到达服务端B,此时B误认为A又发出一次新的连接请求,于是就向A发出确认报文段。如果不采用三次握手,只要B发出确认,就建立新的连接了,此时A不会响应B的确认且不发送数据,则B一直等待A发送数据,浪费资源。
7. TCP四次挥手
- A的应用进程先向其TCP发出连接释放报文段(FIN=1,seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN-WAIT-1(终止等待1)状态,等待B的确认。
- B收到连接释放报文段后即发出确认报文段(ACK=1,ack=u+1,seq=v),B进入CLOSE-WAIT(关闭等待)状态,此时的TCP处于半关闭状态,A到B的连接释放。
- A收到B的确认后,进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。
- B发送完数据,就会发出连接释放报文段(FIN=1,ACK=1,seq=w,ack=u+1),B进入LAST-ACK(最后确认)状态,等待A的确认。
- A收到B的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),A进入TIME-WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL(最大报文段生存时间)后,A才进入CLOSED状态。B收到A发出的确认报文段后关闭连接,若没收到A发出的确认报文段,B就会重传连接释放报文段。
第四次挥手为什么要等待2MSL?
- 保证A发送的最后一个ACK报文段能够到达B。这个ACK报文段有可能丢失,B收不到这个确认报文,就会超时重传连接释放报文段,然后A可以在2MSL时间内收到这个重传的连接释放报文段,接着A重传一次确认,重新启动2MSL计时器,最后A和B都进入到CLOSED状态,若A在TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,则无法收到B重传的连接释放报文段,所以不会再发送一次确认报文段,B就无法正常进入到CLOSED状态。
- 防止已失效的连接请求报文段出现在本连接中。A在发送完最后一个ACK报文段后,再经过2MSL,就可以使这个连接所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现旧的连接请求报文段。
为什么是四次挥手?
- 因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。但是在关闭连接时,当Server端收到Client端发出的连接释放报文时,很可能并不会立即关闭SOCKET,所以Server端先回复一个ACK报文,告诉Client端我收到你的连接释放报文了。只有等到Server端所有的报文都发送完了,这时Server端才能发送连接释放报文,之后两边才会真正的断开连接。故需要四次挥手。
四. HTTP协议
超文本传输协议(HTTP,HyperText Transfer Protocol) 是一种用于传输超文本和多媒体内容的协议,主要是为 Web 浏览器与 Web 服务器之间的通信而设计的。
当我们使用浏览器浏览网页的时候,我们网页就是通过 HTTP 请求进行加载的。
HTTP 使用客户端-服务器模型,客户端向服务器发送 HTTP Request(请求),服务器响应请求并返回 HTTP Response(响应)。
HTTP 协议基于 TCP 协议,发送 HTTP 请求之前首先要建立 TCP 连接也就是要经历 3 次握手。目前使用的 HTTP 协议大部分都是 1.1。在 1.1 的协议里面,默认是开启了 Keep-Alive 的,这样的话建立的连接就可以在多次请求中被复用了。
另外, HTTP 协议是”无状态”的协议,它无法记录客户端用户的状态,一般我们都是通过 Session 来记录客户端用户的状态。
1. 从输入URL到页面加载发送了什么
- DNS解析
- TCP连接
- 发送HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器解析渲染页面
- 连接结束
2. 常见状态码
五. DNS协议
1. 讲解一下域名解析的过程
1.在浏览器中输入www.qq.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。
2.如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。
3.如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/IP参数中设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。
4.如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。
5.如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至 “根DNS服务器”,“根DNS服务器”收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址(qq.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找qq.com域服务器,重复上面的动作,进行查询,直至找到www.qq.com主机。
6.如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。
不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机
2. 递归查询与迭代查询
一、主机向本地域名服务器的查询一般都是采用递归查询。
所谓递归查询就是:如果主机所询问的本地域名服务器不知道被查询的域名的IP地址,那么本地域名服务器就以DNS客户的身份,
向其它根域名服务器继续发出查询请求报文(即替主机继续查询),而不是让主机自己进行下一步查询。
因此,递归查询返回的查询结果或者是所要查询的IP地址,或者是报错,表示无法查询到所需的IP地址。
二、本地域名服务器向根域名服务器的查询的迭代查询。
迭代查询的特点:当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所要查询的IP地址,要么告诉本地服务器:“你下一步应当向哪一个域名服务器进行查询”。
然后让本地服务器进行后续的查询。根域名服务器通常是把自己知道的顶级域名服务器的IP地址告诉本地域名服务器,让本地域名服务器再向顶级域名服务器查询。
顶级域名服务器在收到本地域名服务器的查询请求后,要么给出所要查询的IP地址,要么告诉本地服务器下一步应当向哪一个权限域名服务器进行查询。
最后,知道了所要解析的IP地址或报错,然后把这个结果返回给发起查询的主机
3. DNS缓存策略
简单来说,一条域名的DNS记录会在本地有两种缓存:浏览器缓存和操作系统(OS)缓存。在浏览器中访问的时候,会优先访问浏览器缓存,如果未命中则访问OS缓存,最后再访问DNS服务器(一般是ISP提供),然后DNS服务器会递归式的查找域名记录,然后返回。
DNS记录会有一个ttl值(time to live),单位是秒,意思是这个记录最大有效期是多少。经过实验,OS缓存会参考ttl值,但是不完全等于ttl值,而浏览器DNS缓存的时间跟ttl值无关,每种浏览器都使用一个固定值。