计算机网络经典面试题
自己秋招中遇到的一些经典计算机网络面试题。--by DUT_SanfordZhu
1.请简述TCP\UDP的区别
TCP和UDP是OSI模型中的传输层中的协议。
TCP面向连接,UDP面向非连接
TCP提供可靠的数据传输服务,而UDP无法保证
TCP数据传输慢,UDP数据传输快
TCP提供拥塞控制和流量控制机制,而UDP没有
2.拥塞控制和流量控制
流量控制:如果发送方把数据发送得过快,接收方可能会来不及接收,这就会造成数据的丢失。
TCP的流量控制是利用滑动窗口机制实现的,接收方在返回的数据中会包含自己的接收窗口的大小,以控制发送方的数据发送。
拥塞控制:拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。
两者的区别:流量控制是为了预防拥塞。如:在马路上行车,交警跟红绿灯是流量控制,当发生拥塞时,如何进行疏散,是拥塞控制。流量控制指点对点通信量的控制。而拥塞控制是全局性的,涉及到所有的主机和降低网络性能的因素。
拥塞解决的两种方法:
发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去。但只要网络出现拥塞,拥塞窗口就减小一些,以减少注入到网络中的分组数。
慢开始+拥塞避免
一开始的慢开始算法的指数增长是很恐怖的,所以为了防止拥塞窗口增长过快需要设置一个门限ssthresh
无论在慢开始阶段还是在拥塞避免阶段,只要发送方没有收到确认,就认为这时候拥塞了。
1.就要把慢开始门限设置为此时窗口值的一半
2.然后把拥塞窗口重新设置为1,执行慢开始算法。
快重传+快恢复
快重传要求接收方在收到一个失序的报文段后就立即发出重复确认
如果没有快速重传和快速恢复,TCP将会使用定时器来要求传输暂停。在暂停这段时间内,没有新的数据包被发送。所以快速重传和快速恢复旨在快速恢复丢失的数据包。
快重传的机制还是比较好理解的,如图所示,接收方发现M3丢失,则立即发送对M2的重复确认。一旦发送方一连收到三个M2的重复确认就应当立即重传M3,也就是发送方收到第四个对M2的确认时。
与快重传配合使用的还有快恢复算法,结合上图的实例来分析,其过程有以下两个要点。
1.当发送方连续收到三个重复确认时,就把门限减半。2.考虑到如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将拥塞窗口设置为门限的大小,然后执行拥塞避免算法(加法)。
3.TCP三次握手和四次挥手
为什么不是两次?
为了避免失效的链接请求又传送给服务器端。导致服务器资源的浪费
4.在浏览器中输入url后执行会发生什么?
-
1.首先 Chrome 搜索自身的 DNS 缓存。(如果 DNS 缓存中找到百度的 IP 地址,就跳过了接下来查找 IP 地址步骤,直接访问该 IP 地址。)
-
2.搜索操作系统自身的 DNS 缓存。(浏览器没有找到缓存或者缓存已经失效)
-
3.读取硬盘中的 host 文件,里面记录着域名到 IP 地址的映射关系,Mac 电脑中位于 /etc/hosts。(如果前1.2步骤都没有找到)
-
4.浏览器向宽带运营商服务器或者域名服务器发起一个 DNS 解析请求,这里服务器有两种方式解析请求,这在稍后会讲到,之后浏览器获得了百度首页的 IP 地址。
-
5.拿到 IP 地址后,浏览器就向该 IP 所在的服务器建立 TCP 连接(即三次握手)。
-
6.连接建立起来之后,浏览器就可以向服务器发起 HTTP 请求了。(这里比如访问百度首页,就向服务器发起 HTTP 中的 GET 请求)
-
7.服务器接受到这个请求后,根据路径参数,经过后台一些处理之后,把处理后的结果返回给浏览器,然后会解析和渲染这个页面。
-
8.如果浏览器没有后续的请求,那么就会跟服务器端发起 TCP 断开(即四次挥手)。
5.HTTP协议(超文本传输协议)
特性:
-
HTTP1.0 是无连接无状态的
无连接就是假如某个客户机在短时间多次次请求同一个资源,服务器并不能区别是否已经响应过用户的请求,反而每次都不耐其烦重新响应请求。
无状态就是服务端无法记录客户端的信息
-
HTTP 一般构建于 TCP/IP 协议之上,默认端口号是 80
HTTP 请求由 3 个部分构成,分别是:状态行,请求头(Request Header),请求正文。
状态行由请求方式,路径、协议等构成,各元素之间以空格分隔。对应到图中即为 GET、/books/?sex=man&name=Professional、 HTTP/1.1
请求头提供一些参数比如:Cookie,用户代理信息,主机名等等。(图中即从第二行到最后一行)
请求正文就放一些发送的数据,一般 GET 请求会将参数放在 URL 中,也就是在请求头中而请求正文一般为空,而 POST 请求将参数放在请求正文中。
GET 一般用于信息获取,比如刚才我们浏览百度首页,其使用的就是GET方法。
GET跟POST的区别
GET:对服务器资源的简单请求
POST:用于发送包含用户提交数据的请求,有可能对服务器的数据进行更改
-
GET请求的数据会附在URL后面,POST的数据放在HTTP包体
-
POST安全性比GET安全性高
HTTP响应也是由三个部分构成。分别是:状态行,响应头(Response Header),响应正文。
HTTP 响应中包含一个状态码,用来表示服务器对客户端响应的结果。
状态码一般由3位构成:
-
1xx : 表示请求已经接受了,继续处理。
-
2xx : 表示请求已经处理掉了。
-
3xx : 重定向。
-
4xx : 一般表示客户端有错误,请求无法实现。
-
5xx : 一般为服务器端的错误。
比如常见的状态码:
-
200 OK 客户端请求成功。
-
301 Moved Permanently 请求永久重定向。
-
302 Moved Temporarily 请求临时重定向。
-
304 Not Modified 文件未修改,可以直接使用缓存的文件。
-
400 Bad Request 由于客户端请求有语法错误,不能被服务器所理解。
-
401 Unauthorized 请求未经授权,无法访问。
-
403 Forbidden 服务器收到请求,但是拒绝提供服务。服务器通常会在响应正文中给出不提供服务的原因。
-
404 Not Found 请求的资源不存在,比如输入了错误的URL。
-
500 Internal Server Error 服务器发生不可预期的错误,导致无法完成客户端的请求。
-
503 Service Unavailable 服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常。
知道了 HTTP 请求和响应后,一个完整的流程一般是这样的:
通常,由 HTTP 客户端发起一个请求,建立一个到服务器指定端口(默认是 80 端口)的 TCP 连接。HTTP 服务器则在那个端口监听客户端发送过来的请求。一旦收到请求,服务器(向客户端)发回一个状态行,比如"HTTP/1.1 200 OK",和(响应的)消息,消息的消息体可能是请求的文件、错误消息、或者其它一些信息。
HTTP和HTTPS的区别:
基本概念:
https是在http应用层和tcp传输层之间加入了一个安全层(SSL、TLS) ,加入安全层的主要目的是将传输内容加解密,这样就避免了传输内容被窃听。如下图:
HTTP协议传输的数据都是未加密的,也就是明文的,不安全。HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
HTTPS和HTTP的区别主要如下:
1、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
2、端口不一样,http是80,https是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
HTTPS详解:
一、加密SSL
HTTP 协议本身没有加密机制,但是可以使用 SSL(Secure Socket Layer)/TLS(Transport Layer Security)协议解决 HTTP 的安全性问题。SSL 不仅提供加密处理,还提供了一种证书机制,用于确定客户端或服务器。证书由值得信任的第三方机构颁发,用来证明客户端和服务端是真实存在的。
二、加密方式
1)共享(对称)秘钥加密
所谓共享秘钥加密(Common key crypto system)就是加密和解密都使用相同的秘钥,因此也被称为对称秘钥加密。
使用共享秘钥加密时必须将秘钥也发送给对方 ,这样就存在一个问题,发送的秘钥可能会被攻击者窃听,如果不发送,对方又不能解密。
2)公开(非对称)秘钥加密
公开秘钥加密使用一对非对称的秘钥,一把叫做私有秘钥(private key),另一把叫做公开秘钥(private key)。公开秘钥任何人都可以获得,但是私有秘钥是私有的。通过这种方式,可以很好的解决共享秘钥加密的安全性问题。
使用公开秘钥加密时,发送密文的一方使用公钥加密,对方收到加密的信息后,再使用自己的私钥进行解密。这样不需要发送用来解密的私钥,就不存在秘钥被窃取的风险了。
三、HTTPS 加密方式
HTTPS 采用共享**加密和公开**加密两者并用的混合加密机制。 使用公开**加密方式安全地交换在稍后使用的共享秘钥中的秘钥;确保秘钥是安全的前提下,使用共享秘钥加密方式进行通信。
如何保证公开**加密方式交换的秘钥是安全的呢? 将公钥放在数字证书中 ,数字证书由双方都可依赖的第三方机构颁发,因此只要证书是可信的,公钥就是可信的。
四、HMAC-MD5
1、比如你和对方共享了一个**K,现在你要发消息给对方,既要保证消息没有被篡改,又要能证明信息确实是你本人发的,那么就把原信息和使用K计算的HMAC的值一起发过去。对方接到之后,使用自己手中的K把消息计算一下HMAC,如果和你发送的HMAC一致,那么可以认为这个消息既没有被篡改也没有冒充。
2、MD5就是通过散列对要输出的数据进行摘要,接收到数据时,再同样进行MD5散列,与给定的MD5散列值比较,一致不一致就很清楚了。
6.有哪些私有(保留)地址?
-
A类:10.0.0.0 - 10.255.255.255
-
B类:172.16.0.0 - 172.31.255.255
-
C类:192.168.0.0 - 192.168.255.255
7.OSI七层模型和TCP/IP四层模型
8.临时重定向跟永久重定向的区别
302重定向是暂时的重定向,搜索引擎会抓取新的内容而保存旧的网址。
301重定向是永久的重定向,搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址。
9.你了解的端口及对应的服务
10.简单解释一下ARP协议的工作过程
ARP(地址解析协议)是根据IP地址获取物理地址的一个TCP/IP协议。
11.会话跟踪
会话追踪指的是服务器对用户响应的监视。比如你在访问淘宝登录之后会持续追踪你的会话,记录你的购物车记录等等。
常用方法:
URL 重写:URL 重写技术就是在 URL 结尾添加一个附加数据以标识该会话,把会话 ID 通过 URL 的信息传递过去,以便在服务器进行识别不同的用户。
cookie和session
12.HTTP不同版本协议
HTTP1.0是短连接,每一个请求建立一个TCP连接,请求完成后立马断开连接,在高延迟的场景下影响较明显。
HTTP是基于TCP/IP协议的,创建一个TCP连接是需要经过三次握手的,有一定的开销,如果每次通讯都要重新建立连接的话,对性能有影响。因此最好能维持一个长连接,可以用个长连接来发多个请求。
HTTP/1.1允许HTTP设备在事务处理结束之后将TCP连接保持在打开状态,以便为未来的HTTP请求重用现存的连接。
增加connection header:该header用来说明客户端与服务器端TCP的连接方式,若connection为close则使用短连接,若connection为keep-alive则使用长连接
HTTP2.0中,启用了多路复用,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,避免了阻塞。
13.Socket
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。用于描述IP地址和端口。
建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),TCP/IP提供可供程序员做网络开发所用的接口,这就是Socket编程接口;
14 IP协议:
IP的责任就是把数据从源传送到目的地。IP实现两个基本功能:寻址和分段。IP可以根据数据包包头中包括的目的地址将数据包传送到目的地址,在此过程中IP负责选择传送的道路,这种选择道路称为路由功能。
IP路由控制:是指将分组数据发送到最终目标地址的功能。
多跳路由是指路由器或主机在转发IP数据包时只指定下一个路由器或主机,而不是将到最终目标地址为止的所有通路全部指定出来。因为每一个区间在转发IP数据包时会分别指定下一跳的操作,直至包达到最终的目标地址。
15.TCP粘包
什么是粘包现象?
TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
为什么出现粘包现象?
TCP接收到分组时,并不会立刻送至应用层处理,或者说,应用层并不一定会立即处理;实际上,TCP将收到的分组保存至接收缓存里,然后应用程序主动从缓存里读收到的分组。这样一来,如果TCP接收分组的速度大于应用程序读分组的速度,多个包就会被存至缓存,应用程序读时,就会读到多个首尾相接粘到一起的包。
什么时候需要处理粘包现象?
如果发送方发送的多个分组本来就是同一个数据的不同部分,比如一个很大的文件被分成多个分组发送,这时,当然不需要处理粘包的现象。如果多个分组本毫不相干,甚至是并列的关系,我们就一定要处理粘包问题了。比如,我当时要接收的每个分组都是一个有固定格式的商品信息,如果不处理粘包问题,每个读进来的分组我只会处理最前边的那个商品,后边的就会被丢弃。这显然不是我要的结果。
如何处理粘包?
转到应用层进行处理,有两种途径:
1)格式化数据:每条数据有固定的格式(开始符、结束符),这种方法简单易行,但选择开始符和结束符的时候一定要注意每条数据的内部一定不能出现开始符或结束符;
2)发送长度:发送每条数据的时候,将数据的长度一并发送,比如可以选择每条数据的前4位是数据的长度,应用层处理时可以根据长度来判断每条数据的开始和结束。
附三次握手/四次挥手详解
SEQ:可以帮助我们学习TCP协议以及排查通讯故障,如通过查看***和确认号可以确定数据传输是否乱序。
三次握手即建立TCP连接:
PS:TCP初始化***不能设置为一个固定值,因为这样容易被攻击者猜出后续***,从而遭到攻击。
就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:
(1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
(2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
(3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
为什么不是两次?而是三次?
未连接队列:
在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于 Syn_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。
SYN攻击:
在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了
TCP计时器:
1.重传计时器:
当TCP发送报文段时,就创建该特定报文段的重传计时器 。可能发生两种情况:
(1)、若在计时器截止时间到( 通常是60秒 )之前收到了对此特定报文段的确认,则撤销此计时器。
(2)、若在收到了对此特定报文段的确认之前计时器截止期到,则重传此报文段,并将计时器复位。
2.保活计时器
保活计时器使用在某些实现中,用来防止在两个TCP之间的连接出现长时期的空闲。假定客户打开了到服务器的连接,传送了一些数据,然后就保持静默了。也许这个客户出故障了。在这种情况下,这个连接将永远地处理打开状态。
要解决这种问题,在大多数的实现中都是使服务器设置保活计时器。每当服务器收到客户的信息,就将计时器复位。保活计时器 通常设置为2小时 。若服务器过了2小时还没有收到客户的信息,它就发送探测报文段。若发送了10个探测报文段(每一个相隔75秒)还没有响应,就假定客户出了故障,因而就终止该连接。
3.时间等待计时器
时间等待计时器是在连接终止期间使用的 。当TCP关闭一个连接时,它并不认为这个连接马上就真正地关闭了。在时间等待期间中,连接还处于一种中间过渡状态。这就可以使重复的FIN报文段(如果有的话)可以到达目的站因而可将其丢弃。这个计时器的值 通常设置为一个报文段的寿命期待值的两倍 。
四次挥手:
由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。
(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
整个过程: