(1)OSI 的七层模型分别是?各自的功能是什么?

  • 物理层:建立物理连接,数据以比特流传输。
  • 数据链路层:IP数据报封装成帧,建立逻辑连接,进行硬件地址寻址,如何传输,差错校验等功能。
  • 网络层:进行逻辑地址寻址,实现不同网络之间的路径选择,分组传输,路由器的选择与转发。
  • 传输层:端到端传输数据(如TCP,UDP),流量控制,差错校验等基本功能。
  • 会话层:建立、管理、维护、终止 应用程序进程之间会话。负责在网络中的两节点之间建立、维持和终止通信。
  • 表示层:管理数据的加密和压缩。
  • 应用层:各种应用程序,通过应用进程间的交互来完成特定的网络应用

注:
网络七层模型是一个标准,而非实现。
网络五层模型是一个实现的应用模型,由七层模型简化合并而来。

(2)说一下一次完整的HTTP请求过程包括哪些内容?

  1. 域名解析  ,解析出对应IP地址
  2. 发起TCP三次握手建立连接
  3. 建立TCP连接后,发起HTTP请求
  4. 服务器响应http请求,浏览器得到html代码
  5. 浏览器解析html代码,并请求html代码中的静态资源(html/css/js等)
  6. 然后浏览器渲染,展示给用户

3.建立TCP连接后,发起HTTP请求

HTTP请求报文由三部分组成:请求行,请求头和请求正文
请求行:用于描述客户端的请求方式,请求的资源名称以及使用的HTTP协议的版本号(例GET/books/java.html HTTP/1.1)。
请求头:用于描述客户端请求哪台主机,以及客户端的一些环境信息等。
注:这里提一个请求头 Connection,Connection设置为 keep-alive用于说明 客户端这边设置的是,本次HTTP请求之后并不需要关闭TCP连接,这样可以使下次HTTP请求使用相同的TCP通道,节省TCP建立连接的时间
请求正文:当使用POST, PUT等方法时,通常需要客户端向服务器传递数据。这些数据就储存在请求正文中。

4.服务器端响应http请求,浏览器得到html代码

HTTP响应报文也由三部分组成:状态行,响应头和实体内容
状态行:状态行用于表示服务器对请求的处理结果
响应头:响应头用于描述服务器的基本信息,以及客户端如何处理数据
实体内容:服务器返回给客户端的数据

5.浏览器解析html代码,并请求html代码中的静态资源

浏览器拿到html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,就向服务器端去请求下载(会使用多线程下载,每个浏览器的线程数不一样),这个时候就用上 keep-alive特性了,建立一次HTTP连接,可以请求多个资源,下载资源的顺序就是按照代码里面的顺序,但是由于每个资源大小不一样,而浏览器又是多线程请求请求资源,所以这里显示的顺序并不一定是代码里面的顺序。

(3)常见的HTTP状态码有哪些?

状态码
类别
含义
1XX
Informational(信息性状态码)
接收的请求正在处理
2XX
Success(成功状态码)
请求正常处理完毕
3XX
Redirection(重定向状态码)
需要进行附加操作以完成请求
4XX
Client Error(客户端错误状态码)
服务器无法处理请求
5XX
Server Error(服务器错误状态码)
服务器处理请求出错
1xx 信息:
  • 100 Continue :表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应。
2xx 成功:
  • 200 OK
  • 204 No Content :请求已经成功处理,但是返回的响应报文不包含实体的主体部分。一般在只需要从客户端往服务器发送信息,而不需要返回数据时使用。
  • 206 Partial Content :表示客户端进行了范围请求,响应报文包含由 Content-Range 指定范围的实体内容。
3xx 重定向:
  • 301 Moved Permanently :永久性重定向
  • 302 Found :临时性重定向
  • 303 See Other :和 302 有着相同的功能,但是 303 明确要求客户端应该采用 GET 方法获取资源。
  • 304 Not Modified :如果请求报文首部包含一些条件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果不满足条件,则服务器会返回 304 状态码。
  • 307 Temporary Redirect :临时重定向,与 302 的含义类似,但是 307 要求浏览器不会把重定向请求的 POST方法 改成 GET方法。
4xx 客户端错误:
  • 400 Bad Request :请求报文中存在语法错误。
  • 401 Unauthorized :该状态码表示发送的请求需要有认证信息(BASIC 认证、DIGEST 认证)。如果之前已进行过一次请求,则表示用户认证失败。
  • 403 Forbidde:请求被拒绝。
  • 404 Not Found
5xx 服务器错误:
  • 500 Internal Server Error :服务器正在执行请求时发生错误。
  • 503 Service Unavailable :服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。

(4)你知道DNS是什么?DNS的工作原理?

DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库
通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。
应用层协议,使用UDP传输。

为什么域名解析用UDP协议?

因为UDP快啊!基于UDP的DNS协议只要一个请求、一个应答就够了。
客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过TCP三次握手,这样DNS服务器负载更低,响应更快。
注:
UDP报文的最大长度为512字节,而TCP则允许报文长度超过512字节。当DNS查询超过512字节时,协议的TC标志出现删除标志,这时则使用TCP发送。通常传统的UDP报文一般不会大于512字节。

域名解析过程(工作原理):



1)当用户输入域名时,浏览器先检查自己的缓存中是否 这个域名映射的ip地址,有解析结束。
2)若没命中,则检查操作系统缓存(如Windows的hosts文件)中有没有解析过的结果,有解析结束。
3)若无命中, 则向本地域名服务器(LDNS)进行递归查询。
4)若LDNS没有命中,本地域名服务器采用迭代查询,向一个根域名服务器进行查询。根域名服务器返回给LDNS一个顶级域名服务器IP地址。
5) 此时LDNS再发向顶级域名服务器进行查询, 接受请求的顶级域名服务器,查找并返回这个域名对应的Name Server(该网站注册的域名服务器)的IP地址。
6) Name Server根据映射关系表找到目标IP, 连同一个TTL值返回给LDNS。
7) LDNS缓存这个域名和对应的ip, 并把解析的结果返回给用户。
8)用户根据TTL值将解析结果缓存到本地系统缓存中,域名解析过程至此结束。
注:
主机向本地域名服务器的查询一般都是采用递归查询
本地域名服务器向根域名服务器的查询的迭代查询

(5)DNS负载均衡是什么策略?

当一个网站有足够多的用户的时候,假如同时对同一台服务器发起资源请求,那么这台服务器随时可能会蹦掉。处理办法就是用DNS负载均衡技术。
原理:在DNS服务器中为同一个主机名配置多个IP地址。在应答DNS查询时,DNS服务器对每个查询将以DNS主机文件中记录的IP地址按顺序返回不同的解析结果,将客户端的访问引导到不同的机器上去,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的。(例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等)

(6)DNS什么时候采用tcp协议,什么时候采用udp协议?

DNS服务器间进行区域传输的时候用TCP 53,其他的时候如客户端域名解析时DNS服务器用UDP 53
区域传输:一个区中主DNS服务器从自己本机的数据文件中读取该区的DNS数据信息,而辅助DNS服务器则从区的主DNS服务器中读取该区的DNS数据信息。
域名解析:通过主机名,最终得到该主机名对应的IP地址的过程
域名解析使用UDP协议的原因:
域名解析时一般返回的内容都不超过512字节,使用udp传输。不用经过TCP三次握手,这样DNS服务器负载更低,响应更快。
(注:当域名解析的反馈报文的长度超过512字节时,将不能使用udp协议进行解析,此时必须使用tcp。但是通常传统的UDP报文一般不会大于512字节)。
区域传输使用TCP协议的原因:
区域传输的数据量相比单次DNS查询的数据量要大得多。
区域传输对数据的可靠性要求高,因此使用TCP协议。

(7)HTTP长连接和短连接的区别

在HTTP/1.0中默认使用短连接(非持续性连接)。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。
(如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话)
而从HTTP/1.1起,默认使用长连接(持续性连接),用以保持连接特性。
(在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间)

(8)为什么服务器会缓存这一项功能?如何实现的?

原因:
  1. 缓解服务器压力。
  2. 降低客户端获取资源的延迟。
实现方法:
  1. 让代理服务器进行缓存。
  2. 让客户端浏览器进行缓存。

(9)HTTP请求方法你知道多少?

客户端发送的 请求报文 第一行为请求行,包含了方法字段。
根据 HTTP 标准,HTTP 请求可以使用多种请求方法。
HTTP1.0 定义了三种请求方法: GETPOSTHEAD方法。
HTTP1.1 新增了六种请求方法:OPTIONSPUTPATCHDELETETRACECONNECT 方法。

(10)GET和POST的区别,你知道哪些?

  1. get是获取数据,post是修改数据
  2. get把请求的数据放在URL上, 以?分割URL和传输数据,参数之间以&相连,所以get不太安全。而post把数据放在HTTP的包体内(requrest body)
  3. get提交的数据最大是2k( 限制实际上取决于浏览器), post理论上没有限制。
  4. GET产生一个TCP数据包,浏览器会把http header和data一并发送出去,服务器响应200(返回数据); POST产生两个TCP数据包,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。(注:header 和 body 分开发送是部分浏览器或框架的请求方法,不属于 post 必然行为,有的不分开发送)
  5. GET请求会被浏览器主动缓存,而POST不会,除非手动设置。
  6. 本质区别:GET是幂等的,而POST不是幂等的
幂等性:对数据库的一次操作和多次操作获得的结果是一致的。简单来说意味着对同一URL的多个请求应该返回同样的结果。
CET请求方式符合幂等性,事实上GET请求可能会出现多次请求的结果(例如在两次请求中间对数据库中的数据作了更改),从这来说是不符合幂等性的定义,但是因为GET请求只是查询数据库,不会对数据库做任何更改,因此也认为是幂等的。
POST请求方式不符合幂等性,请求方式每次获得的结果都有可能不一样,因为POST请求是作用在上一级的URL上的,则每一次请求都会添加一份新资源。
正因为它们有这样的区别,所以不应该且不能用get请求做数据的增删改这些有副作用的操作。

(11)GET方法参数写法是固定的吗?

在约定中,参数是写在 ? 后面,用 & 分割
我们知道,解析报文的过程是通过获取 TCP 数据,用正则等工具从数据中获取 Header 和 Body,从而提取参数。
比如header请求头中添加token,来验证用户是否登录等权限问题。
也就是说,我们可以自己约定参数的写法,只要服务端能够解释出来就行。

(12)GET方法的长度限制是怎么回事?

网络上都会提到浏览器地址栏输入的参数是有限的。
首先说明一点,HTTP 协议没有 Body 和 URL 的长度限制,对 URL 限制的大多是浏览器和服务器的原
服务器是因为处理长 URL 要消耗比较多的资源,为了性能和安全(防止恶意构造长 URL 来攻击)考虑,会给 URL 长度加限制。

(13)POST方法比GET方法安全?

有人说POST 比 GET 安全,因为数据在地址栏上不可见。
然而,从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,只要在网络节点上捉包,就能完整地获取数据报文。
要想安全传输,就只有加密,也就是 HTTPS。

(14)POST方法产生俩个数据包?

有些文章中提到,POST 会将 header 和 body 分开发送,先发送 header,服务端返回 100 状态码再发送 body。
HTTP 协议中没有明确说明 POST 会产生两个 TCP 数据包,而且实际测试(Chrome)发现,header 和body 不会分开发送。
所以,header 和 body 分开发送是部分浏览器或框架的请求方法,不属于 post 必然行为。

(15)TCP连接和HTTP请求之间的问题

一个TCP连接可以对应几个HTTP请求?

如果维持连接,一个 TCP 连接是可以发送多个 HTTP 请求的。

一个TCP连接中的HTTP请求发送可以一起发送么(比如一起发三个请求,再三个响应一起接收)?

HTTP/1.1 存在一个问题,单个 TCP 连接在同一时刻只能处理一个请求,意思是说:两个请求的生命周期不能重叠,任意两个 HTTP 请求从开始到结束的时间在同一个 TCP 连接里不能重叠。
  • HTTP/1.1存在 Pipelining 技术可以完成这个多个请求同时发送,但是由于浏览器默认关闭,所以可以认为这是不可行的。
  • HTTP2中由于 Multiplexing 特点的存在,多个 HTTP 请求可以在同一个 TCP 连接中并行进行。
那么在 HTTP/1.1 时代,浏览器是如何提高页面加载效率的呢?
1.维持和服务器已经建立的 TCP 连接,在同一连接上顺序处理多个请求。
2.和服务器建立多个 TCP 连接。

浏览器对同一 Host 建立 TCP 连接到数量有没有限制?

假设我们还处在 HTTP/1.1 时代,那个时候没有多路传输,当浏览器拿到一个有几十张图片的网页该怎么办呢?肯定不能只开一个 TCP 连接顺序下载,那样用户肯定等的很难受,但是如果每个图片都开一个TCP 连接发 HTTP 请求,那电脑或者服务器都可能受不了,要是有 1000 张图片的话总不能开 1000 个TCP 连接吧,你的电脑同意 NAT 也不一定会同意。
有限制。Chrome 最多允许对同一个 Host 建立六个 TCP 连接。不同的浏览器有一些区别。
注:
如果图片都是 HTTPS 连接并且在同一个域名下,那么浏览器在 SSL 握手之后会和服务器商量能不能用HTTP2,如果能的话就使用 Multiplexing 功能在这个连接上进行多路传输。不过也未必会所有挂在这个域名的资源都会使用一个 TCP 连接去获取,但是可以确定的是 Multiplexing 很可能会被用到。如果发现用不了 HTTP2 呢?或者用不了 HTTPS(现实中的 HTTP2 都是在 HTTPS 上实现的,所以也就是只能使用 HTTP/1.1)。那浏览器就会在一个 HOST 上建立多个 TCP 连接,连接数量的最大限制取决于浏览器设置,这些连接会在空闲的时候被浏览器用来发送新的请求,如果所有的连接都正在发送请求呢?那其他的请求就只能等等了。

(16)在浏览器中输入url地址后显示主页的过程?

  1. 根据域名,进行DNS域名解析;
  2. 拿到解析的IP地址,建立TCP连接;
  3. 向IP地址,发送HTTP请求;
  4. 服务器处理请求;
  5. 返回响应结果;
  6. 关闭TCP连接;
  7. 浏览器解析HTML;
  8. 浏览器布局渲染;

1.为主机申请IP:DHCP动态主机配置协议

首先需要一个IP地址,告诉网络我是谁。这就需要DHCP动态主机配置协议。
1) 主机的操作系统生成一个DHCP请求报文
2) 并将这个报文放入具有目的端口67(DHCP服务器的固定端口)和原端口68(DHCP客户端的固定端口)的UDP报文段。
3) 该UDP报文段则被放置在一个具有广播IP目的地址(255.255.255.255)和源IP地址(0.0.0.0)的IP数据报中。
4) 在数据链路层添加头部封装成包含DHCP请求的广播以太网帧,该以太网帧包含源MAC地址(自己的MAC)和目的MAC地址(FF:FF:FF:FF:FF:FF)。
5) 以太网帧被发送到交换机,交换机修改转发表记录我的MAC (自学习:每接收到一个帧都记录该帧的MAC和到达的接口),然后在他的所有出口广播这个帧。
6)与交换机相连的默认网关路由器接收到了这个广播帧,进行解析,提取出IP数据报,发现目的IP是广播IP,就交给传输层,传输层又提取出 DHCP 请求交给应用层, DHCP服务器就收到了该 DHCP 请求(DHCP服务器一般运行在路由器中,路由器的路由功能只是它众多功能的一种,他还可以支持别的协议,比如这里的DHCP协议)。
7)DHCP 服务器为此生成一个 DHCP ACK 报文,主要包含:分配给DHCP请求的IPDNS服务器的IP默认网关路由器的IP子网掩码;这个报文再被传输层、网络层、数据链路层一路封装成帧,该帧的目的MAC 是我的MAC,源MAC是接收 DHCP 请求帧的路由器端口的 MAC
8)DHCP ACK以太网帧由默认网关路由器发送给交换机,交换机根据转发表转发回给我的主机
9)主机收到该帧之后再从链路层到应用层,层层提取,最后得到DHCP ACK报文,从而记录自己的IP、DNS服务器IP、默认网关路由器IP,子网掩码。

2.查找默认网关路由器的MAC地址:ARP地址转换协议

在前面 DHCP 过程中我们已经得到了 DNS 服务器的 IP 地址,现在只要去访问该IP就好,但是在这之前我们需要先走出我们所处的局域网,这就需要局域网默认网关路由器的MAC地址(通过默认网关离开主机所在的局域网)
为什么需要局域网的MAC地址呢
因为局域网内是通过 MAC 进行识别的,为什么要用 MAC 地址识别呢?是这样的,以前没这么多主机的时候,IP 是固定的,我们就不需要 MAC,但现在主机越来越多,这就导致局域网里 IP 不是十分充足,管理起来也不是很好管理,所以 IP 每隔一段时间就会被回收,需要的时候才会被分配,这也就是为什么前面提到的 DHCP 动态主机配置协议会存在,所以这个 IP 是会变的,对于主机来说,唯一不变的是 MAC,所以,在局域网内部我们是用 MAC 定位的。
10)主机生成一个 ARP 查询报文,目的 IP 是默认网关路由器,这个报文最终被封装成以太网帧,帧的目的MAC是 FF:FF:FF:FF:FF:FF(广播地址),然后把帧发给交换机,交换机看到是广播地址就给广播出去。
11)默认网关路由器接收到了这个帧,经过层层拆封提取得到 ARP 报文,发现其中的目的 IP 跟他自己某个接口的 IP 匹配,就发送回去一个 ARP应答报文给主机,这里包含了他自己的MAC地址。

3.查找目的域名的IP:DNS域名系统

现在我们拿到了默认网关路由器的MAC,可以离开局域网去DNS服务器查目的域名的IP了
12)主机上的操作系统生成了包含目的域名的DNS查询报文,并将该DNS查询报文放置在一个具有53号目的端口(DNS服务器目的端口)的UDP报文段中,层层封装成以太网帧,帧的目的 MAC 是默认网关路由器的 MAC地址。
13)默认网关路由器接收到该帧之后,提取出IP数据报,并根据路由表进行转发,因为路由器具有内部网关协议*(RIP路由信息协议、OSPF开放最短路径优先协议)和外部网关协议(BGP边界网关协议)*,因此路由表中已经配置了可以从路由器到达 DNS 服务器的路由表项。
14)DNS 服务器接收到帧后,层层提取出 DNS 查询报文,并在 DNS 数据库中查找待解析域名对应的 IP,找到之后发送 DNS 应答报文,封装成 UDP 报文段,再放入 IP 数据报,最后通过路由器发给源主机的默认网关路由器,再经由交换机转发给源主机。

4.web客户—服务器交互:TCP和HTTP

有了目的域名的IP后就可以访问HTTP服务器了,有了HTTP服务器的IP地址之后,主机操作系统能够生成TCP套接字,该套接字将用于向HTTP服务器发送HTTP GET报文
15)主机中的TCP首先与HTTP服务器中的TCP进行三次握手来建立TCP连接(生成一个具有80号目的端口的TCP SYN 报文段,并发送给HTTP服务器)。
16)包含TCP SYN的数据报到达HTTP服务器后,从数据报中读出TCP SYN报文并分解到与端口号80相联系的欢迎套接字。对于HTTP服务器与我的主机之间的TCP连接生成一个连接套接字,生成一个TCP SYNACK报文段,发回给主机后从而建立连接。
17)连接建立之后,浏览器生成一个HTTP GET报文写入TCP套接字中。
18)HTTP服务器从TCP套接字读取HTTP GET报文,生成一个HTTP响应报文,将Web页面内容放入报文主体中,并将报文发送进TCP套接字中。
19)浏览器从套接字读取HTTP响应报文后,从HTTP响应报文中抽取Web网页的html,并最终显示web网页。

(17)HTTPS和HTTP的区别

  1. HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全, HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比HTTP协议安全。
  2. HTTPS协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。
  3. HTTP和HTTPS使用的是完全不同的连接方式,HTTP端口号为80,HTTPS端口号为443。

(18)什么是SSL/TLS?

SSL(Secure Socket Layer,安全套接字层)。它是一种用于保证应用程序进程和Web服务器之间发送数据的私密性,完整性和可鉴别性的协议层。
TLS(Transport Layer Security,传输层安全)。SSL的标准化,是更为安全的升级版SSL。
SSL/TLS协议作用:认证用户和服务器,加密数据,维护数据的完整性。

(19)HTTPS是如何保证数据传输的安全,整体的流程是什么?(SSL是怎么工作保证安全的)

HTTPS 采用混合的加密机制,使用非对称密钥加密传输对称密钥来保证密钥传输过程的安全,之后使用对称密钥加密进行通信来保证通信过程的效率和安全。
1)客户端向服务器端发起SSL连接请求。
2)服务器把公钥证书发送给客户端。
3)客户端验证证书为有效后,使用伪随机数生成器生成通信加密所使用的对称密钥,再用公钥对对称秘钥进行加密,并发送给服务器端。
4)服务器利用自己的私钥解密这个消息,从而得到对称密钥。
5)进行数据传输,服务器和客户端双方用这个对称秘钥对数据进行加密解密,可以保证在数据收发过程中的安全。

如何保证公钥不被篡改?

将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。

公钥加密计算量太大,如何减少耗用的时间?

每一次对话,客户端和服务器端都生成一个"对话密钥",用它来加密信息。由于"对话密钥"是对称加密,所以运算速度非常快,而服务器公钥只用于加密"对话密钥"本身从而安全传送"对话密钥",用“对话密钥”来加密数据内容,这样就减少了加密运算的消耗时间。

对称密钥和非对称密钥加密的优缺点?

1.对称密钥:
  • 优点:加密速度快。
  • 缺点:无法直接安全地将密钥传输给通信方,无法用来签名。
2.非对称密钥:
  • 优点:可以直接安全地将公钥传输给通信方;可以用来签名。
  • 缺点:加密速度慢。

(20)HTTP如何禁用缓存?如何确认缓存?

HTTP/1.1 通过 Cache-Control 首部字段来控制缓存。
禁止进行缓存:
no-store 指令规定不能对请求或响应的任何一部分进行缓存。
Cache-Control: no-store
强制确认缓存:
no-cache 指令规定缓存服务器需要先向源服务器验证缓存资源的有效性,只有当缓存资源有效时才能使用该缓存对客户端的请求进行响应。
Cache-Control: no-cache

(21)Cookie和Session了解一下?

背景:Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。
Cookie和Session的出现弥补了HTTP协议无状态的不足。

Cookie和Session是什么?

Cookie:实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
Session:是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。服务器把客户端信息以某种形式记录在服务器上。这就是Session。如果客户端请求里不包含有SESSION ID,则为该客户端创建一个SESSION并生成一个与此SESSION相关的SESSION ID。客户端浏览器再次访问时,服务器就按照这个SESSION ID把这个SESSION从服务器的内存中查找出来。
如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了(利用SESSION ID),对客户来说更轻了。

Cookie和Session的工作原理


1)浏览器端第一次发送请求到服务器端。
2)服务器端创建Cookie,该Cookie中包含用户的信息,服务器会通过响应携带Cookie,在产生响应时会产生Set-Cookie响应头,然后将该Cookie发送到浏览器端。
3)当浏览器再次向服务器发送请求时,会产生Cookie请求头,将之前服务器的Cookie信息再次发送给了服务器
4)服务器端通过Cookie中携带的数据跟踪用户状态。

1)浏览器端第一次发送请求到服务器端
2)服务器端创建一个Session,同时会创建一个特殊的Cookie(name为JSESSIONID的固定值,value为session对象的ID),然后将该Cookie发送至浏览器端。
3)浏览器端再次访问服务器端时就会携带该name为JSESSIONID的Cookie对象。
4)服务器端根据name为JSESSIONID的Cookie的value(sessionId),在服务器内查找对应的Session对象,从而跟踪到用户状态。

Cookie与Session的对比

1)存储方式
  • Cookie是string类型
  • Session是object类型
2)存储位置
  • Cookie存放在客户浏览器上
  • Session存放在服务器上
3)安全性
  • Cookie以明文方式存放在客户端,容易泄露,安全性弱。(可以加密后存放)
  • Session存放在服务器上,对客户端透明。安全性强。
4)有效期
  • Cookie保存在硬盘中,只需要设置MaxAge属性值为比较大的正整数,即使关闭浏览器,Cookie还是存在的。(MaxAge表示Cookie生命周期是累计固定的)
  • Session保存在服务器中,设置MaxInactiveInterval属性值来确定Session的有效期。并且Session依赖于名为JSESSIONID的Cookie,该Cookie默认的MaxAge属性为-1(表示仅当前浏览器内有效,并且各浏览器窗口间不共享),如果关闭了浏览器,该Session虽然没有从服务器中消亡,但是会失效。(MaxInactiveInterval表示Session的生命周期是间隔变化的,比如每访问一次就重新记时,若整个间隔时间内没有访问则失效)
5)对服务器的负担
  • Cookie是保存在客户端上的。不占用服务器资源。
  • Session是保存在服务器上的,每个用户都会产生一个Sessioon,如果并发访问的用户非常多,Session会消耗大量的内存,应当用Cookie。
6)浏览器的支持上
  • 如果浏览器禁用Cookie,那么Cookie是无用的。
  • 如果浏览器禁用Cookie,Session可以通过URL地址重写来进行会话跟踪。

Session和cookie应该如何去选择(适用场景)?

  • Cookie 只能存储 ASCII 码字符串,而 Session 则可以存储任何类型的数据,因此在考虑数据复杂性时首选 Session
  • Cookie 存储在浏览器中,容易被恶意查看。如果非要将一些隐私数据存在 Cookie 中,可以将Cookie 值进行加密,然后在服务器进行解密。
  • 对于大型网站,不建议将所有的用户信息都存储到 Session 中。因为如果用户所有的信息都存储在 Session 中,那么开销是非常大的,

什么是URL地址重写?

URL地址重写是对客户端不支持Cookie的解决方案。
原理:将该用户Session的id信息重写到URL地址中。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。

(*22)SQL注入攻击了解吗?

攻击者在HTTP请求中注入恶意的SQL代码,服务器使用参数构建数据库SQL命令时,恶意SQL被一起构造,并在数据库中执行。
例:
有这样一个用户登录场景:登录界面包括用户名和密码输入框,以及提交按钮。输入用户名和密码,提交。
这是一个post请求,登录时调用接口learn.me/sql/login.html,首先连接数据库,然后后台对post请求参数中携带的用户名、密码进行参数校验,即sql的查询过程。假设正确的用户名和密码为user和pwd123,输入正确的用户名和密码、提交,相当于调用了以下的SQL语句:
SELECT * FROM user WHERE username = 'user' ADN password = 'pwd123'
由于用户名和密码都是字符串,SQL注入方法即把参数携带的数据变成mysql中注释的字符串。
'#':'#'后所有的字符串都会被当成注释来处理
用户名输入:user'#,密码随意输入,如:111,然后点击提交按钮。等价于SQL语句:
SELECT * FROM user WHERE username = 'user'#'ADN password = '111'
'#'后面都被注释掉了,相当于:
SELECT * FROM user WHERE username = 'user' 
这导致可能输入一个错误的密码或者不输入密码就可登录用户名为'user'的账号,这是十分危险的事情。
如何防范SQL注入攻击?
Web端:
1)有效性检验。
2)限制字符串输入的长度。
服务端:
1)不用拼接SQL字符串。
2)使用预编译的PrepareStatement。
3)有效性检验。(为什么服务端还要做有效性检验?第一准则,外部都是不可信的,防止攻击者绕过Web端请求)
4)过滤SQL需要的参数中的特殊字符。比如单引号、双引号。

(23)端口有效范围是多少到多少?

UDP和TCP报头使用两个字节存放端口号,所以端口号的有效范围是从0 - 65535。
一般用到的是1到65535(16位),其中0不使用。
  • 1-1023为知名端口号,知名端口即众所周知的端口号,范围从0到1023,这些端口号一般固定分配给一些服务。
  • 1024-49151为用户端口号,用户端口由IANA负责分配,需要走申请流程,申请手续相对系统端口来说不那么严格。
  • 49152-65535称为动态端口号,动态端口一般不固定分配给某个服务,也就是说许多服务都可以使用这些端口。
常用端口记录:
端口
协议
20(数据)/21(控制) FTP 文件传输服务
22
SSH 远程连接服务
23 TELNET 终端仿真服务
25 SMTP 简单邮件传输服务
53 DNS 域名解析服务
80 HTTP 超文本传输服务
443 HTTPS 加密的超文本传输服务
3306 MYSQL数据库端口
3389 WIN2003远程登陆
8080 TCP服务端
8888
Nginx服务器
67/68(UDP) DHCP主机动态配置服务

(*24)HTTP中缓存的私有和共有字段?知道吗?

private指令规定了将资源作为私有缓存,表示只有用户的浏览器可以缓存private响应,不允许任何中继Web代理对其进行缓存。
Cache-Control: private
public指令规定了将资源作为公共缓存,表示该响应可以在浏览器或者任何中继的Web代理中缓存,public是默认值。
Cache-Control: public                 

(25)DDos攻击了解吗?

DDos(分布式拒绝服务):指的是处于不同位置的多个攻击者同时向一个或数个目标发动攻击,是一种分布的、协同的大规模攻击方式。单一的DoS攻击一般是采用一对一方式的,它利用网络协议和操作系统的一些缺陷,采用欺骗和伪装的策略来进行网络攻击,使网站服务器充斥大量要求回复的信息,消耗网络带宽或系统资源,导致网络或系统不胜负荷以至于瘫痪而停止提供正常的网络服务。
攻击流程分为2个阶段:
  • 搜集肉鸡:攻击者可以通过各种手段搜集肉鸡,包括购买他人非法入侵获得的肉鸡、自己实施入侵并传播木马、租赁服务器和带宽等。在此过程中,攻击者必然会在肉鸡上种植木马,以便统一集中控制和发动攻击指令。
  • 发动攻击:攻击者发出指令,让肉鸡同时发起攻击,发送大量攻击的网络数据包,耗尽目标网络带宽或者其他资源,导致被攻击目标无法提供正常服务。
攻击后果:攻击者可以通过多台肉鸡同时发送大量垃圾数据,造成大流量的数据包,导致服务器带宽耗尽,正常玩家无法发送网络数据包,服务器无法及时反馈数据,服务运营被迫中断。
攻击方式

SYN Flood
SYN Flood攻击是当前网络上最为常见的DDoS攻击,它利用了TCP协议实现上的一个缺陷。通过向网络服务所在端口发送大量的伪造源地址的攻击报文,就可能造成目标服务器中的半连接队列被占满,从而阻止其他合法用户进行访问。
UDP Flood
UDP Flood是日渐猖厥的流量型DDoS攻击,原理也很简单。常见的情况是利用大量UDP小包冲击DNS服务器或Radius认证服务器、流媒体视频服务器。由于UDP协议是一种无连接的服务,在UDP Flood攻击中,攻击者可发送大量伪造源IP地址的小UDP包。
ICMP Flood ICMP Flood攻击属于流量型的攻击方式,是利用大的流量给服务器带来较大的负载,影响服务器的正常服务。由于目前很多***直接过滤ICMP报文。因此ICMP Flood出现的频度较低。
Connection       Flood
Connection Flood是典型的利用小流量冲击大带宽网络服务的攻击方式,这种攻击的原理是利用真实的IP地址向服务器发起大量的连接。并且建立连接之后很长时间不释放,占用服务器的资源,造成服务器上残余连接(WAIT状态)过多,效率降低,甚至资源耗尽,无法响应其他客户所发起的链接。
HTTP Get
这种攻击主要是针对存在ASP、JSP、PHP、CGI等脚本程序,特征是和服务器建立正常的TCP连接,并不断的向脚本程序提交查询、列表等大量耗费数据库资源的调用。这种攻击的特点是可以绕过普通的***防护,可通过Proxy代理实施攻击,缺点是攻击静态页面的网站效果不佳,会暴露攻击者的lP地址。
UDP DNS Query Flood
UDP DNS Query Flood攻击采用的方法是向被攻击的服务器发送大量的域名解析请求,通常请求解析的域名是随机生成或者是网络世界上根本不存在的域名。域名解析的过程给服务器带来了很大的负载,每秒钟域名解析请求超过一定的数星就会造成DNS服务器解析域名超时。
如何防御DDos攻击:
  • 采用高性能的网络设备
  • 尽量避免NAT的使用
  • 充足的网络带宽保证
  • 升级主机服务器硬件
  • 把网站做成静态页面
  • 安装专业抗DDOS***
无论是路由器还是硬件防护墙设备要尽量避免采用网络地址转换NAT的使用,因为采用此技术会较大降低网络通信能力,其实原因很简单,因为NAT需要对地址来回转换,转换过程中需要对网络包的校验和进行计算,因此浪费了很多CPU的时间,但有些时候必须使用NAT,那就没有好办法了。
大量事实证明,把网站尽可能做成静态页面,不仅能大大提高抗攻击能力,而且还给黑客入侵带来不少麻烦,至少到现在为止关于HTML的溢出还没出现,若你非需要动态脚本调用,那就把它弄到另外一台单独主机去,免的遭受攻击时连累主服务器,当然,适当放一些不做数据库调用脚本还是可以的,此外,最好在需要调用数据库的脚本中拒绝使用代理的访问,因为经验表明使用代理访问你网站的80%属于恶意行为。

(26)MTU和MSS分别是什么?

MTU(Maximum Transmit Unit 最大传输单元):即物理接口(数据链路层)提供给其上层的(通常是IP层)最大一次传输数据的大小。
MTU由硬件规定,以普遍使用的以太网接口为例,缺省MTU=1500 Byte,这是以太网接口对IP层的约束,如果IP层有<=1500 byte 需要发送,只需要一个IP包就可以完成发送任务;如果IP层有> 1500 byte 数据需要发送,需要分片才能完成发送,这些分片有一个共同点,即 IP头部标识 相同。
MSS(Maximum Segment Size 最大分段大小)MSS是TCP用来限制应用层的最大发送字节数,即TCP提交给IP层最大分段大小,不包含 TCP头部 和  TCP选项,只包含 TCP有效载荷。
如果底层物理接口MTU= 1500 byte,则 MSS = 1500- 20(IP Header) -20 (TCP Header) = 1460 byte,如果应用层有2000 byte发送,需要两个报文段才可以完成发送,第一个TCP报文段= 1460,第二个TCP报文段= 540。

(27)HTTP中有个缓存机制,但如何保证缓存是最新的呢?(缓存过期机制)

浏览器为什么要缓存?
首先当我们访问网页的时候,很多大的图片从服务器上传输过来的时候,试想一下,如果浏览器不把图片缓存下来而是每次都要到服务器去取,那么每次都给服务器和网络造成了巨大的负担。
(1) max-age 指令设置缓存的最大有效时间,单位为秒(s)。
Cache-Control: max-age=31536000
(2) Expires 首部字段设置缓存的过期时间。
Expires: Wed, 04 Jul 2012 08:26:05 GMT
在 HTTP/1.0 中,max-age 指令会被忽略掉。
在 HTTP/1.1 中,会优先处理 max-age 指令(max-age会覆盖Expires)。

(28)为何需要把 TCP/IP 协议栈分成 5 层(或7层)?开放式回答。

ARPANET 的研制经验表明,对于复杂的计算机网络协议,其结构应该是层次式的。
分层的好处:
  1. 隔层之间是独立的
  2. 灵活性好
  3. 结构上可以分隔开
  4. 易于实现和维护
  5. 能促进标准化工作

(29)谈谈TCP吧?

TCP是什么?

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

TCP头部中有哪些信息?


  • 源端口号  目的端口号(16bit)
  • 序号(32bit):传输方向上字节流的字节编号。(初始时序号会被设置一个随机的初始值(ISN),之后每次发送数据时,序号值 = ISN + 数据在整个字节流中的偏移。假设A -> B且ISN = 1024,第一段数据512字节已经到B,则第二段数据发送时序号为1024 + 512。用于解决网络包乱序问题)
  • 确认号(32bit):接收方对发送方TCP报文段的响应,其值是收到的序号值 + 1。(是期待收到对方下一个报文段的第一个数据字节的序号)
  • 首部长(4bit):表示首部长度为 4 * 首部长 字节。(首部长最大为15,即60字节)
  • 窗口(16bit):接收窗口。用于告知对方(发送方)本方的缓冲还能接收多少字节数据。用于解决流控。
  • 校验和(16bit):接收端用CRC检验整个报文段有无损坏
  • 标志位(6bit):
URG
标志紧急指针是否有效
ACK
标志确认号是否有效(确认报文段)。用于解决丢包问题
PSH
提示接收端立即从缓冲读走数据
RST
表示要求对方重新建立连接(复位报文段)
SYN
表示请求建立一个连接(连接报文段)
FIN
表示关闭连接(断开报文段)

TCP的特点?

  • TCP是面向连接的
  • 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的(一对一)
  • TCP提供可靠交付的服务。通过TCP连接传送的数据,无差错、不丢失、不重复、并且按序到达
  • TCP提供全双工通信。TCP允许通信双方的应用进程在任何时候都能发送数据。TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双方通信的数据
  • 面向字节流。TCP中的“流”(stream)指的是流入进程或从进程流出的字节序列。“面向字节流”的含义是:虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流

TCP有限状态机了解?


常见TCP的连接状态有哪些?

  • CLOSED:初始时没有任何连接的状态。
  • LISTEN:服务器监听来自客户端的连接请求(SYN包)。
  • SYN_SENT:客户端socket执行CONNECT连接,发送SYN包,之后等待来自服务器的SYN ACK包(服务器的连接请求和对客户端连接请求的确认)。
  • SYN_RCVD:服务端收到客户端的SYN包并发送服务端SYN ACK包,之后等待客户端对连接请求的确认(ACK包)。
  • ESTABLISH:表示连接建立。客户端发送了最后一个ACK包后进入此状态,服务端接收到ACK包后进入此状态。
  • FIN_WAIT_1:终止连接的一方(通常是客户机)发送了FIN包后进入此状态,之后等待对方FIN包。
  • CLOSE_WAIT:(假设服务器)接收到客户机FIN包之后等待关闭的阶段。在接收到对方的FIN包之后,自然是需要立即回复ACK包的,表示已经知道断开请求。但是本方是否立即断开连接(发送FIN包)取决于是否还有数据需要发送给客户端,若还有数据要发送,则在发送FIN包之前均为此状态。
  • FIN_WAIT_2:客户端接收到服务器的ACK包,但并没有立即接收到服务端的FIN包,进入FIN_WAIT_2状态。此时是半连接状态,即有一方要求关闭连接,等待另一方关闭。
  • LAST_ACK:服务端发动最后的FIN包,等待最后的客户端ACK包。
  • CLOSING:当主动关闭方处于FIN_WAIT_1时,被动关闭方的 FIN 先于之前的自己发送的 ACK 到达,主动关闭方就直接FIN_WAIT_1 -> CLOSING,(其实就相当于同时关闭),然后迟来的 ACK 到达时,主动关闭方就从CLOSING -> TIME_WAIT。
  • TIME_WAIT:客户端收到服务端的FIN包,并立即发出ACK包做最后的确认,在此之后的2MSL(两倍的最长报文段寿命)时间称为TIME_WAIT状态

(30)说一下TCP三次握手,为什么要三次握手?

三次握手过程


三次握手其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。
主要作用:就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传输做准备。实质上其实就是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换 TCP窗口大小 信息。
初始状态客户端处于 Closed 的状态,服务端处于 Listen 状态,进行三次握手。
  • 第一次握手:客户端给服务端发一个 SYN 报文段,并指明客户端的初始化序列号 ISN(c)。此时客户端处于 SYN_SENT 状态。(在SYN报文段中同步位SYN=1,初始序号seq=x)SYN=1的报文段不能携带数据,但要消耗掉一个序号。
  • 第二次握手:服务器收到客户端的 SYN 报文段之后,会以自己的 SYN 报文段作为应答,并且也是指定了自己的初始化序列号 ISN(s)。同时会把客户端的 ISN(c) + 1 作为ACK 的值,表示自己已经收到了客户端的 SYN报文,此时服务器处于 SYN_RCVD 的状态。(在SYN ACK报文段中SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y)
  • 第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 ISN(s) + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,双方已建立起了连接。(在ACK报文段中ACK=1,确认号ack=y+1,序号seq=x+1)ACK报文段可以携带数据,不携带数据则不消耗序号(第二次握手的既是ACK也是SYN报文段所以不可以)
发送第一个SYN的一端将执行主动打开(active open),接收这个SYN并发回下一个SYN的另一端执行被动打开(passive open)。在socket编程中,客户端执行connect()时,将触发三次握手。

为什么需要三次握手,两次不行吗?

原因1:相互确认
两次握手只能保证单向连接是畅通的
第一次握手:客户端发送网络包,服务端收到了。  服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
第二次握手:服务端发包,客户端收到了。             客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。
第三次握手:客户端发包,服务端收到了。             服务端就能得出结论:客户端的接收能力、服务器发送能力也是正常的。
因此,需要三次握手才能确认双方的接收与发送能力是否正常。
原因2:防止重复连接
三次握手的主要原因是为了防止旧的重复连接引起连接混乱问题。
在网络状况比较复杂或者网络状况比较差的情况下(丢包),发送方可能会连续发送多次建立连接的请求。如果 TCP 握手的次数只有两次,这个被客户端认为失效的消息到达了服务器端,对服务器端而言,以为这是一个新的请求连接消息,就向客户端发送确认并建立连接。对于客户而言,它认为没有给服务器再次发送连接请求(因为上次的通话已经结束)所以客户忽略服务器的这个确认从而不发送数据,但是服务器则会一直等待客户的消息而处于忙等状态。这就导致了服务器资源被浪费。
所以如果 TCP 是三次握手的话,因为客户没有向服务器发出确认(即第三次握手),由于服务器一段时间内收不到确认,就知道客户没有要求建立连接从而不会一直处于忙等状态。

(31)什么是半连接队列?

在 TCP 三次握手的时候,操作系统内核会维护两个队列,分别是:
  • 半连接队列,也称 SYN 队列;
  • 全连接队列,也称 accepet 队列;
服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下的请求连接放在半连接队列中。
当完成三次握手后,内核会把连接从半连接队列移除,然后创建一个新的完全连接,并将其添加到全连接队列中。

注:
不管是半连接队列还是全连接队列,都有最大长度限制,超过限制时,内核会直接丢弃,或返回 RST 包。
关于SYN-ACK 重传次数的问题: 服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行重传,如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。

(32)TCP为什么采用随机初始序列号ISN?

当一端为建立连接而发送它的SYN时,它为连接选择一个初始序号。ISN随时间而变化,因此每个连接都将具有不同的ISN
RFC1948中提出了一个较好的初始化序列号ISN随机生成算法。
ISN = M + F(localhost, localport, remotehost, remoteport).
M是一个计时器,这个计时器每隔4毫秒加1。
F是一个Hash算法,根据源IP、目的IP、源端口、目的端口生成一个随机数值。要保证hash算法不能被外部轻易推算得出,用MD5算法是一个比较好的选择。
  • 如果TCP每次连接都使用固定ISN,黑客可以很方便模拟任何IP与server建立连接。
  • 广域网的随机性,复杂性都很高,假设网络连接状况不好。那么之前交互的报文很可能在断开连接之前还没到到server。如果ISN是固定的,那很可能在新连接建立后,上次连接通信的报文才到达,这种情况有概率发生老报文的seq号正好是server希望收到的新连接的报文seq。这就乱了。

(33)说一下TCP四次挥手,为什么要四次挥手?

四次挥手过程


TCP 的连接的拆除需要发送四个包,因此称为四次挥手,客户端或服务器均可主动发起挥手动作。
初始状态:双方都处于 ESTABLISHED 状态,假如是客户端先发起关闭请求。进行四次挥手。
  • 第一次挥手客户端发送一个 FIN 报文段,即发送 连接释放报文段(FIN=1,序号seq=u)。并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认。
  • 第二次挥手服务端收到 FIN报文段 后,发送 一个 ACK报文段(ACK=1,确认号ack=u+1,序号seq=v)。服务端进入CLOSE_WAIT(关闭等待)状态,此时的TCP处于半关闭状态,客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务端发出 FIN 报文段。
  • 第三次挥手服务器将最后的数据发送完毕后,就向客户端发送 FIN ACK报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。
  • 第四次挥手 即客户端收到服务端的 FIN ACK报文段 后,发送一个 ACK报文段(ACK=1,序号seq=u+1,确认号ack=w+1),客户端进入TIME_WAIT(时间等待)状态。服务端收到 ACK 报文段 后进入CLOSED 状态。但此时TCP连接未释放掉,需要等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
收到一个 FIN报文段 只意味着在这一个方向上没有数据流动。在socket编程中,任何一方执行close()操作即可产生挥手操作。

挥手为什么需要四次?

如果参照三次握手机制,讲道理说挥手也可以只需要需要三次。假如挥手只有三次,服务器收到客户端发送请求断开连接的 FIN报文段 后,同时回 ACK和FIN报文段 给客户端,最后再收到客户端回的 ACK报文段 后连接就关闭了。
但是客户端发送完数据后请求断开连接,服务端可能还有数据需要发送,若同时回 ACK和FIN报文段给客户端,可能造成数据的损坏或错误。所以服务器先发送ACK报文段,等服务端的数据发送完了后,再发送 FIN ACK报文段,就可以保证传输数据的完整性。

四次挥手后等待2MSL的意义?

MSL(Maximum Segment Lifetime 最长报文段寿命),它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
两个理由:
  1. 保证第四次握手客户端发送的最后一个 ACK报文段 能够到达服务端。 第四次握手客户端给服务端发送最后一个 ACK报文段 后,启动计时器记时2MSL。因为这个 ACK报文段 有可能丢失,使得处于LAST-ACK状态的服务端收不到对已发送的 FIN ACK报文段 的确认,服务端等待 t<1MSL 后重传 FIN ACK报文段,且这个报文段在t<1MSL内能够到达客户端,所以能够保证客户端在发送完最后ACK报文段后的 2MSL时间内 收到这个重传的 FIN ACK报文段。接着客户端重传一次ACK报文段,同时重新启动2MSL计时器,最后客户端和服务端都进入到CLOSED状态。若客户端在TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,当这个 ACK报文段 被丢失时则无法收到服务端重传的FIN+ACK报文段,所以也不会再发送一次 ACK报文段,则服务端无法正常进入到CLOSED状态
  2. 防止“已失效的连接请求报文段”出现在本连接中。 客户端在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。
注:
在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。

(34)什么是TCP粘包/拆包?发生的原因?

现在假设客户端向服务端连续发送了两个数据包,用packet1和packet2来表示,那么服务端收到的数据可以分为三种,现列举如下:
第一种情况:接收端正常收到两个数据包,即没有发生拆包和粘包的现象,此种情况不在本文的讨论范围内

第二种情况:接收端只收到一个数据包,由于TCP是不会出现丢包的,所以这一个数据包中包含了发送端发送的两个数据包的信息,这种现象即为粘包。这种情况由于接收端不知道这两个数据包的界限,所以对于接收端来说很难处理。

第三种情况:这种情况有两种表现形式,如下图。接收端收到了两个数据包,但是这两个数据包要么是不完整的,要么就是多出来一块,这种现象说明发生了拆包和粘包。这两种情况如果不加特殊处理,对于接收端同样是不好处理的。



粘包、拆包发送的原因:
  1. 流量控制,拥塞控制。要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包。
  2. 数据包过大。待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。
  3. nagle算法。要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包。
  4. 读取速度小于接收速度。接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包。
解决方案:
  • 格式化数据:每条数据有固定的格式(开始符和结束符),接收端通过这个边界就可以将包拆分开。选择开始符和结束符时一定要确保每条数据的内部不包含开始符和结束符。
  • 发送长度:发送每条数据时,将数据的长度一并发送。例如规定数据的前4位是数据的长度,应用层在处理时可以根据长度来判断每个分组的开始和结束位置。(更推荐)
  • 固定长度:发送端将每个数据包封装成固定长度(不够的可以通过补0填充)

(35)谈谈UDP吧?

UDP是什么?

UDP(User Datagram Protocol 数据报协议)是一种面向无连接的传输层通信协议,提供尽最大努力的数据传输服务。(不保证数据传输的可靠性)

UDP头部中有哪些信息?


  • 源端口号 目的端口号(16bit)
  • 长度(16bit) :UDP数据报的长度(包括数据和首部),其最小值为8(仅有首部)。
  • 校验和(16bit):接收端用CRC检验整个报文段有无损坏。

UDP的特点?

  • UDP是无连接的
  • UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态(这里面有许多参数)
  • UDP是面向报文
  • UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
  • UDP支持一对一、一对多、多对一和多对多的交互通信
  • UDP的首部开销小,只有8个字节,比TCP的20个字节的首部要短

(36)TCP和UDP的区别?


TCP UDP
是否连接
面向连接
无连接的
是否可靠
可靠传输,使用流量控制和拥塞控制
尽最大努力交付,即不保证可靠传输
传输方式
面向字节流
面向报文
连接对象个数
只能是一对一通信
支持一对一、一对多、多对一、多对多的交互通信
首部开销
首部开销20~60字节
首部开销更小,只有8个字节
适用场景
适用于要求可靠传输的应用(文件传输)
适用于实时应用(IP电话、视频会议、直播等)

(37)SYN攻击是什么?

服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击。
SYN攻击原理:Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。
SYN 攻击是一种典型的 DDoS 攻击。
常见的防御 SYN 攻击的方法:
  1. 缩短超时(SYN Timeout)时间
  2. 增加最大半连接数
  3. 过滤网关防护
  4. SYN cookies技术
什么是SYN Cookie?
SYN Cookie就是用一个Cookie来响应TCP SYN请求的TCP实现。
当Server接收到一个Client的SYN数据包时,Server通过特定的算法把 半开连接信息 编码成“Cookie”,随SYN-ACK包一同发给Client,这样在连接完全建立前B不保存任何信息。
缺点:最明显的就是B不保存连接的半开状态,就丧失了重发SYN-ACK消息的能力,这一方面会降低正常用户的连接成功率。

(38)网络层常见协议?可以说一下吗?

协议
名称 作用
IP 网际协议
IP协议不但定义了数据传输时的基本单元和格式,还定义了数据报的递交方法和路由选择
ICMP
网际控制报文协议
ICMP就是一个错误侦测与回报机制,其目的就是让我们能够检测网路的连线状况﹐也能确保连线的准确性,是ping和traceroute的工作协议
RIP 路由信息协议
RIP是一种基于距离矢量算法的协议,它使用 跳数 作为度量来衡量到达目的网络的距离。
IGMP
Internet组管理协议
用于实现组播、广播等通信

(39)TCP的拥塞控制了解吗?

TCP拥塞控制主要是四个算法:
  1. 慢启动
  2. 拥塞控制
  3. 快重传
  4. 快恢复
(1)慢启动:开始开始发送方拥塞窗口cwnd=1,之后每发发送一条报文段且收到ACK后将cwnd+1,所以慢开始每一轮发送增长一倍,cwnd呈指数型快速增长,直到重传或者到达门限ssthresh。
(2)拥塞控制:每经过一个传输轮次,拥塞窗口cwnd=cwnd+1,使拥塞窗口cwnd按线性规律缓慢增,直到出现重传。
(3)快重传:要求接收方不要等待自己发送数据时才捎带确认,而是要立刻发送确认,即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认,发送方一旦收到3个连续的重复确认,就将相应的报文段立即重传,而不是等待该报文段的超时计时器超时再重传(快重传之后配合快恢复,对于个别丢失的报文段,发送方不会出现超时重传,也就不会误认为出现了拥塞而将cwnd降低为1,而是将ssthresh=cwnd/2且设置新的cwnd=ssthresh并线性增长,使用快重传可以整个网络吞吐量提高约20%)
(4)快恢复:发送方调整门限值ssthresh=cwnd/2,同时设置拥塞窗口cwnd=ssthresh,并开始执行拥塞避免算法。
一般来说,TCP拥塞控制默认认为网络丢包是由于网络拥塞导致的,所以一般的TCP拥塞控制算法以丢包为网络进入拥塞状态的信号。
对于丢包有两种判定方式:
  1. 超时重传RTO超时
  2. 收到三个重复确认ACK
拥塞控制过程:

(40)为何快速重传是选择3次ACK,快重传快恢复机制的作用是什么?

收到 两次重复ACK 很可能是乱序造成的!收到 三次重复ACK 很可能是丢包造成的!收到四次或者更多次重复ACK更更可能是丢包造成的,但是这样的响应策略太慢。因为丢包肯定会造成三次重复ACK!所以选择收到 三个重复ACK 时窗口减半效果最好,这是实践经验。
个人理解:
  • 三次重复的ACK,可能是丢包引起的,丢包可能是网络拥塞造成的,也可能是信号失真造成的。
  • 三次重复的ACK,也有可能是乱序引起的,而乱序和网络拥塞没有直接关系。
首先为什么要快速重传和快恢复机制?如果是等到超时重传RTO超时把窗口cwnd重新设置为1后开始 慢增长、拥塞控制,效率会显得慢。因为超时重传说明丢包,但少量丢包不意味着一定拥塞,很可能由于其他因素引起,而因为非拥塞导致的丢包致使窗口cwnd重新减小到1,显然会降低通信效率。
如果采用快重传和快恢复机制,收到三次重复ACK就将门限ssthresh=cwnd/2,再将窗口cwnd=ssthersh而不是重新从1增长,这样整体通信效率会提高。
虽然收到三次重复ACK不能代表一定会出现丢包,但是可以说明网络状态不是特别好,可能将出现丢包和拥塞。因此可以适当把窗口cwnd缩小一点,让网络整体通信量缓解消化一下,不说一定避免拥塞但是可以有效缓解拥塞到来的形势,并且同时保持一定窗口cwnd大小,保持通信量(收到三次重复ACK是网络不好的征兆,但也只是可能,只是征兆而已,所以应该适当减小cwnd但也要保持一定大小)。这样既可以达到减缓网络负担甚至避免拥塞,又可以保持一定的网络吞吐量。

(41)你了解流量控制原理吗?

接收方通过TCP首部窗口字段告知发送方本方可接收的最大数据量,用以解决发送速率过快导致接收方不能接收的问题。所以流量控制是点对点的控制
TCP是全双工协议,双方可以同时通信,所以发送方接收方各自维护一个发送窗和接收窗。窗口用来限制发送或者接受数据的大小。其中发送窗口的大小由接收方返回的TCP报文段中窗口字段来控制,接收方通过此字段告知发送方自己的缓冲,从而发送方根据其缓冲调整自己发送窗口的大小。
大小。
注:
  • 窗口字段的值指的是 发送本报文段的一方 的接收窗口(而非自己的发送窗口。窗口值告诉对方,从本报文段首部中的确认后ack算起,发送本报文段的一方 目前允许对方发送的数据量),该窗口值作为 发送本报文段的一方 让 接收本报文段的一方 设置其发送窗口的依据。
  • 发送窗内数据只有当接收到接收端某段发送数据的ACK响应时才移动发送窗,左边缘紧贴刚被确认的数据。接收窗也只有接收到数据且最左侧连续时才移动接收窗口。

(42)如何区分流量控制和拥塞控制?

流量控制 拥塞控制
属于通信双方协商,端到端的问题
涉及通信链路全局,全局性的过程
需要通信双方各维护一个发送窗、一个接收窗。对任意一方,接收窗大小由自身决定,发送窗大小由接收方响应的TCP报文段中窗口值确定
拥塞窗口大小变化由试探性发送一定数据量数据探查网络状况后而自适应调整
实际最终发送窗口 = min{流量控制发送窗口,拥塞控制窗口}
()建立TCP时服务端和客户端的系统调用过程是怎样的?

服务器:
1)创建socket -> int socket(int domain, int type, int protocol);
domain:协议域,决定了socket的地址类型,IPv4为AF_INET。
type:指定socket类型,SOCK_STREAM为TCP连接。
protocol:指定协议。IPPROTO_TCP表示TCP协议,为0时自动选择type默认协议。
2)绑定socket和端口号 -> int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd:socket返回的套接字描述符,类似于文件描述符fd。
addr:有个sockaddr类型数据的指针,指向的是被绑定结构变量。
addrlen:地址长度。
// IPv4的sockaddr地址结构
struct sockaddr_in {
    sa_family_t sin_family;    // 协议类型,AF_INET
    in_port_t sin_port;        // 端口号
    struct in_addr sin_addr;   // IP地址
};
struct in_addr {
    uint32_t s_addr;
}
3)监听端口号 -> int listen(int sockfd, int backlog);
sockfd:要监听的sock描述字。
backlog:socket可以排队的最大连接数。
4)接收用户请求 -> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sockfd:服务器socket描述字。
addr:指向地址结构指针。
addrlen:协议地址长度。
注:一旦accept某个客户机请求成功将返回一个全新的描述符用于标识具体客户的TCP连接。
5)从socket中读取字符 -> ssize_t read(int fd, void *buf, size_t count);
fd:连接描述字。
buf:缓冲区buf。
count:缓冲区长度。
注:大于0表示读取的字节数,返回0表示文件读取结束,小于0表示发生错误。
6)关闭socket -> int close(int fd);
fd:accept返回的连接描述字,每个连接有一个,生命周期为连接周期。
注:sockfd是监听描述字,一个服务器只有一个,用于监听是否有连接;fd是连接描述字,用于每个连接的操作。

客户机:
1)创建socket -> int socket(int domain, int type, int protocol);
连接指定计算机 -> int connect(int sockfd, struct sockaddr* addr, socklen_t addrlen);
sockfd:客户端的sock描述字。
addr:服务器的地址。
addrlen:socket地址长度。
2)向socket写入信息 -> ssize_t write(int fd, const void *buf, size_t count);
fd:连接描述字。
buf:缓冲区buf。
count:缓冲区长度。
注:大于0表示写了部分或全部数据,小于0表示出错。
3)关闭oscket -> int close(int fd);
fd:accept返回的连接描述字,每个连接有一个,生命周期为连接周期。

(43)TCP 协议如何保证可靠传输?

  1. 校验和:TCP报文头有校验和,用于校验报文是否损坏。
  2. 序号、确认号机制:确保了数据是按序、完整到达。
  3. 超时重传:保证接收方未接受到的数据能够因多次重发而最终被接收。
  4. 连接管理:通信前先三次握手建立连接,通信完四次挥手释法连接。
  5. 流量控制:通过TCP首部窗口字段,协调发送端发送窗口和接受端接收窗口的大小,控制发送的速度。
  6. 拥塞控制:通过拥塞控制相应措施,防止过多数据注入网络,使得网络负载正常,防止网络拥塞而引起丢包。

(44)常见的数据链路层协议?可以说一下吗?

协议
名称
作用
ARP
地址解析协议
根据IP地址获取MAC地址
RARP
反向地址转换协议
根据MAC地址获取IP地址
PPP
点对点协议
为 在点对点连接上传输多协议数据包 提供了一个标准方法。设计目的主要是用来通过拨号或专线方式建立点对点连接发送数据,使其成为各种主机、网桥和路由器之间简单连接的一种共通的解决方案。

(*45)什么是RARP?工作原理?

RARP:反向地址转换协议(网络层协议)
RARP与ARP工作方式相反。 RARP使只知道自己硬件地址的主机能够知道其IP地址。RARP发出要反向解释的物理地址并希望返回其IP地址,应答包括能够提供所需信息的RARP服务器发出的IP地址。

RARP的工作原理:

1)主机发送一个本地RARP广播包。在广播包中,声明自己的MAC地址并且请求任何收到此请求的RARP服务器分配一个IP地址。
2)本地网段的RARP服务器收到此请求后,检查器RARP列表,查找该MAC地址对应的IP地址。
3 )如果存在,RARP服务器就给源主机发送一个响应数据包,并将IP地址提供给对方主机使用。 如果不存在,RARP服务器对此不做任何响应。
4)源主机收到从RARP服务的响应信息,就利用得到的IP地址进行通信。如果一直没收到RARA服务器的响应信息,表示初始化失败。

ARP与RARP的比较:

相同点:
  • 对于ARP与RARP,request是广播,而reply是单播。
不同点:
  • 协议的目的完全不同。
  • 发送ARP packet的是路由器,而RARP不是。
  • ARP server在kernel中,而RARP是一个用户进程。

(46)Ping命令基于哪一层协议?原理是什么?

ping命令基于网络层的命令,是基于ICMP协议(Internet控制报文协议)工作的。
作用:简单来说,ping命令 用来探测本机与网络中另一主机之间是否可达,如果两台主机之间ping不通,则表明这两台主机不能建立起连接。ping是定位网络通不通的一个重要手段。
原理:ping命令 是基于 ICMP协议 来工作的。ping 命令会发送一份 ICMP回显请求报文 给目标主机,并等待目标主机返回 ICMP回显应答报文。因为ICMP协议会要求目标主机在收到消息之后,必须返回ICMP应答消息给源主机,如果源主机在一定时间内收到了目标主机的应答,则表明两台主机之间网络是可达的。

(47)可以解释一下RTO,RTT和超时重传分别是什么吗?

RTO:从上一次发送数据,因为长期没有收到ACK响应,到下一次重发之间的时间。就是重传时间间。通常每次重传RTO是前一次RTO的两倍,计量单位通常是RTT(例:1RTT,2RTT,4RTT,8RTT......),重传次数到达上限之后停止重传。
RTT:数据从发送到接收到对方响应之间的时间间隔,即数据报在网络中一个往返用时。大小不稳定。
超时重传:发送端发送报文后若长时间未收到确认报文则需要重发该报文。
引起超时重传的原因:
  1. 发送的数据没能到达接收端。
  2. 接收端接收到数据,但是ACK报文在返回过程中丢失。
  3. 接收端拒绝或丢弃数据。

(*48)XSS攻击是什么?如何防范?

跨站点脚本攻击,指攻击者通过篡改网页,嵌入恶意脚本程序,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式。
如何防范XSS攻击?
  • 前端,服务端,同时需要字符串输入的长度限制。
  • 前端,服务端,同时需要对HTML转义处理。将其中的”<”,”>”等特殊字符进行转义编码。
防范XSS的核心是必须对输入的数据做过滤处理

(*49)CSRF攻击你知道吗?如何防范?

跨站点请求伪造,指攻击者通过跨站请求,以合法的用户的身份进行非法操作。
可以这么理解CSRF攻击:攻击者盗用你的身份,以你的名义向第三方网站发送恶意请求。CRSF能做的事情包括利用你的身份发邮件,发短信,进行交易转账,甚至盗取账号信息。
如何防范CSRF攻击?
  • 安全框架:例如Spring Security。
  • token机制:在HTTP请求中进行token验证,如果请求中没有token或者token内容不正确,则认为CSRF攻击而拒绝该请求。
  • 验证码:通常情况下,验证码能够很好的遏制CSRF攻击,但是很多情况下,出于用户体验考虑,验证码只能作为一种辅助手段,而不是最主要的解决方案。
  • referer识别:在HTTP Header中有一个字段Referer,它记录了HTTP请求的来源地址。如果Referer是其他网站,就有可能是CSRF攻击,则拒绝该请求。但是,服务器并非都能取到Referer。很多用户出于隐私保护的考虑,限制了Referer的发送。在某些情况下,浏览器也不会发送Referer,例如HTTPS跳转到HTTP。
1)验证请求来源地址;
2)关键操作添加验证码;
3)在请求地址添加 token 并验证。

(*50)文件上传漏洞是如何发生的?如何防范?

文件上传漏洞指的是用户上传一个可执行的脚本文件,并通过此脚本文件获得了执行服务端命令的能力。
如何防范文件上传漏洞?
  • 文件上传的目录设置为不可执行
  • 判断文件类型。在判断文件类型的时候,可以结合使用MIME Type,后缀检查等方式。因为对于上传文件,不能简单地通过后缀名称来判断文件的类型,因为攻击者可以将可执行文件的后缀名称改为图片或其他后缀类型,诱导用户执行。
  • 对上传的文件类型进行白名单校验,只允许上传可靠类型。
  • 对上传的文件进行重新命名,使攻击者无法猜想上传文件的访问路径,将极大地增加攻击成本,同时向shell.php.rar.ara这种文件,因为重命名而无法成功实施攻击。
  • 限制上传文件的大小
  • 单独设置文件服务器的域名