网络全部总结

1. 说说HTTP常用的状态码及其含义?

不管是不是面试需要,我们都要知道,日常开发中的这几个状态码的含义:

请添加图片描述
101:服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到Http的新版本协议,Http切为websocket。服务器已经理解了客户端的请求,并将通过Upgrade 消息头通知客户端采用不同的协议来完成这个请求。
在这里插入图片描述

2. HTTP 常用的请求方式,区别和用途?

请添加图片描述

3. 请简单说一下你了解的端口及对应的服务?

请添加图片描述

4. 说下计算机网络体系结构

思路: 这道题主要考察候选人,计算机网络体系结构这个基础知识点。计算机网路体系结构呢,有三层:OSI七层模型、TCP/IP四层模型、五层体系结构。大家可以记住这个图,如下

请添加图片描述

4.1 ISO七层模型

ISO七层模型是国际标准化组织(International Organization for Standardization)制定的一个用于计算机或通信系统间互联的标准体系。

  • 应用层:网络服务与最终用户的一个接口,常见的协议有:HTTP FTP SMTP SNMP DNS
  • 表示层:数据的表示、安全、压缩。确保一个系统的应用层所发送的信息可以被另一个系统的应用层读取。
  • 会话层:建立、管理、终止会话,对应主机进程,指本地主机与远程主机正在进行的会话。
  • 传输层:定义传输数据的协议端口号,以及流控和差错校验,协议有TCP UDP
  • 网络层:进行逻辑地址寻址,实现不同网络之间的路径选择,协议有ICMP IGMP IP等
  • 数据链路层:在物理层提供比特流服务的基础上,建立相邻结点之间的数据链路。
  • 物理层:建立、维护、断开物理连接。
4.2 TCP/IP 四层模型
  • 应用层:对应于OSI参考模型的(应用层、表示层、会话层)。
  • 传输层:对应OSI的传输层,为应用层实体提供端到端的通信功能,保证了数据包的顺序传送及数据的完整性。
  • 网际层:对应于OSI参考模型的网络层,主要解决主机到主机的通信问题。
  • 网络接口层:与OSI参考模型的数据链路层、物理层对应。
4.3 五层体系结构
  • 应用层:对应于OSI参考模型的(应用层、表示层、会话层)。
  • 传输层:对应OSI参考模型的的传输层
  • 网络层:对应OSI参考模型的的网络层
  • 数据链路层:对应OSI参考模型的的数据链路层
  • 物理层:对应OSI参考模型的的物理层。

5 如何理解HTTP协议是无状态的

如何理解无状态这个词呢?

当浏览器第一次发送请求给服务器时,服务器响应了;如果同个浏览器发起第二次请求给服务器时,它还是会响应,但是呢,服务器不知道你就是刚才的那个浏览器。简言之,服务器不会去记住你是谁,所以是无状态协议。

可以通过一个生活中的例子,来更好理解并记住它:

有状态场景:

  • 小红:今天吃啥子?
  • 小明:罗非鱼~
  • 小红:味道怎么样呀?
  • 小明:还不错,好香。

无状态的场景:

  • 小红:今天吃啥子?
  • 小明:罗非鱼~
  • 小红:味道怎么样呀?
  • 小明:?啊?你说啥?什么鬼?什么味道怎么样?

Http加了Cookie的话

  • 小红:今天吃啥子?
  • 小明:罗非鱼~
  • 小红:你今天吃的罗非鱼,味道怎么样呀?
  • 小明:还不错,好香。

6.从浏览器地址栏输入url到显示主页的过程

HTTP的请求过程,DNS解析,TCP三次握手,四次挥手这几个要点,我们都可以讲下。

  1. DNS解析,查找域名对应的IP地址。
  2. 与服务器通过三次握手,建立TCP连接
  3. 向服务器发送HTTP请求
  4. 服务器处理请求,返回网页内容
  5. 浏览器解析并渲染页面
  6. TCP四次挥手,连接结束
    请添加图片描述

7. 说下HTTP/1.0,1.1,2.0的区别

HTTP/1.0默认是短连接,可以强制开启,HTTP/1.1默认长连接,HTTP/2.0采用多路复用。

HTTP/1.0

  • 默认使用短连接,每次请求都需要建立一个TCP连接。它可以设置Connection: keep-alive 这个字段,强制开启长连接。

HTTP/1.1

  • 引入了持久连接(Persistent Connection),即TCP连接默认不关闭,可以被多个请求复用,使用Connection:close关闭。下图是1.1与1.0连接的区别。
    在这里插入图片描述
  • HTTP1/1.1的缺点是必须等下上一个请求接受才能发起下一个请求,所以会收到前面请求的阻塞。 因为请求响应的顺序必须和请求发送的顺序一致,如果中间有某个响应花了很长的时间,后面的响应就算已经完成了也要排队等阻塞的请求返回,这就是线头阻塞。
  • 分块传输编码(Chunked transfer encoding):将响应主体分成若干块,并在每一块前面加上该块数据的长度以及回车换行,这样Recipient(如浏览器)就可以根据这个长度值正确接收每一块数据,最后以一个0长度的分块作为消息体的结束标志。采用该传输方式Sender在开始传输响应内容到Recipient前不需要知道内容的长度。
    例:如要发送的内容(消息体)为:123456789那么消息体的格式为:
    9<CR><LF>
    123456789<CR><LF>
    0<CR><LF>
    好处:
    1、不需要缓存数据,由于在服务器发送数据到Recipient前不需要知道数据的字节长度,所以可以动态产生响应内容而不用先将所有数据进行缓存。
    2、分块传输编码允许服务器在最后发送消息头字段。对于那些头字段值在内容被生成之前无法知道的情形非常重要,例如消息的内容要使用散列进行签名,散列的结果通过HTTP消息头字段进行传输。没有分块传输编码时,服务器必须缓冲内容直到完成后计算头字段的值并在发送内容前发送这些头字段的值。
    3、HTTP服务器有时使用压缩(gzip或deflate)以缩短传输花费的时间。分块传输编码可以用来分隔压缩对象的多个部分。在这种情况下,块不是分别压缩的,而是整个负载进行压缩,压缩的输出使用本文描述的方案进行分块传输。在压缩的情形中,分块编码有利于一边进行压缩一边发送数据,而不是先完成压缩过程以得知压缩后数据的大小。
  • 管道机制,即在同一个TCP连接里面,客户端可以同时发送多个请求。在这里插入图片描述

HTTP/2.0

  • 二进制协议,1.1版本的头信息是文本(ASCII编码),数据体可以是文本或者二进制;2.0中,头信息和数据体都是二进制。
  • 完全多路复用,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应。 每一个TCP连接中承载了多个双向流通的流,每一个流都有一个独一无二的标识和优先级,而流就是由二进制帧组成的。二进制帧的头部信息会标识自己属于哪一个流,所以这些帧是可以交错传输,然后在接收端通过帧头的信息组装成完整的数据。这样就解决了线头阻塞的问题,同时也提高了网络速度的利用率。
  • 报头压缩,HTTP协议不带有状态,每次请求都必须附上所有信息。Http/2.0引入了头信息压缩机制,使用gzip或compress压缩后再发送。
  • 服务端推送,允许服务器未经请求,主动向客户端发送资源。

8 POST和GET有哪些区别?

请添加图片描述
GET和POST本质上没有区别 ,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。

悖论
GET产生一个TCP数据包,POST产生两个TCP数据包:
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据),而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

其实大多数http post请求,都是一个tcp包发出去的,也就是不存在所谓的先发一个头,然后发body的。
大多数框架都是尽量在一个tcp包里面把HTTP请求发出去的,但是也确实存在先发HTTP头,然后发body的框架。但是具体发多少个TCP包,这个是代码的问题,是tcp协议栈的问题,跟HTTP没关系。
以okhttp为例:
(1)如果客户端的请求头里面有这样的映射:Expect:100-continue,那么客户端先发送第一个包:请求头,并且阻塞读取服务端的回复。
(2)然后服务端如果满足客户端的期望的话,会发送100continue,否则发送417.
(3)客户端读取到服务器的状态行的响应码 如果是100 continue,那么客户端就得继续发送RequestBody,否则就结束请求。回到(1)这里,如果没有Expect的请求头,那么客户端不会先发送请求头的,会把请求头和RequestBody一起发送给服务器。以上

9. 在交互过程中如果数据传送完了,还不想断开连接怎么办,怎么维持?

在HTTP中响应体的Connection字段指定为keep-alive即可

10. HTTP 如何实现长连接?在什么时候会超时?

HTTP的长连接实质是指TCP的长连接。至于什么时候超时,我们记住这几个参数如tcp_keepalive_timetcp_keepalive_probes就好啦

什么是HTTP的长连接?

  1. HTTP分为长连接和短连接,本质上说的是TCP的长短连接。TCP连接是一个双向的通道,它是可以保持一段时间不关闭的,因此TCP连接才具有真正的长连接和短连接这一说法哈。
  2. TCP长连接可以复用一个TCP连接,来发起多次的HTTP请求,这样就可以减少资源消耗,比如一次请求HTML,如果是短连接的话,可能还需要请求后续的JS/CSS。

如何设置长连接?

通过在头部(请求和响应头)设置Connection字段指定为keep-alive,HTTP/1.0协议支持,但是是默认关闭的,从HTTP/1.1以后,连接默认都是长连接。

在什么时候会超时呢?

  • HTTP一般会有httpd守护进程,里面可以设置keep-alive timeout,当tcp连接闲置超过这个时间就会关闭,也可以在HTTP的header里面设置超时时间。
  • TCP 的keep-alive包含三个参数,支持在系统内核的net.ipv4里面设置;当 TCP 连接之后,闲置了tcp_keepalive_time,则会发生侦测包,如果没有收到对方的ACK,那么会每隔 tcp_keepalive_intvl再发一次,直到发送了tcp_keepalive_probes,就会丢弃该连接。
1. tcp_keepalive_intvl = 15
2. tcp_keepalive_probes = 5
3. tcp_keepalive_time = 1800

11. HTTP 与 HTTPS 的区别。

可以从安全性、数据是否加密、默认端口等这几个方面去回答

我的答案如下

HTTP,即超文本传输协议,是一个基于TCP/IP通信协议来传递明文数据的协议。HTTP会存在这几个问题

  • 请求信息是明文传输,容易被窃听截取。
  • 没有验证对方身份,存在被冒充的风险
  • 数据的完整性未校验,容易被中间人篡改

为了解决Http存在的问题,Https出现啦。

HTTPS= HTTP+SSL/TLS,可以理解Https是身披SSL(Secure Socket Layer,安全套接层)的HTTP。它们主要区别如下:

请添加图片描述

12 . Https流程是怎样的?

公私钥、数字证书、加密、对称加密、非对称加密

  • HTTPS = HTTP + SSL/TLS,也就是用SSL/TLS对数据进行加密和解密,Http进行传输。
  • SSL,即Secure Sockets Layer(安全套接层协议),是网络通信提供安全及数据完整性的一种安全协议。
  • TLS,即Transport Layer Security(安全传输层协议),它是SSL3.0的后续版本。

请添加图片描述

Https工作流程

  1. 客户端发起Https请求,连接到服务器的443端口。
  2. 服务器必须要有一套数字证书(证书内容有公钥、证书颁发机构、失效日期等)。
  3. 服务器将自己的数字证书发送给客户端(公钥在证书里面,私钥由服务器持有)。
  4. 客户端收到数字证书之后,会验证证书的合法性。如果证书验证通过,就会生成一个随机的对称密钥,用服务器证书的公钥加密。
  5. 客户端将公钥加密后的密钥发送到服务器。
  6. 服务器接收到客户端发来的密文密钥之后,用自己之前保留的私钥对其进行非对称解密,解密之后就得到客户端的密钥,然后用客户端密钥对返回数据进行对称加密,传输的数据都是密文啦。
  7. 服务器将加密后的密文返回到客户端。
  8. 客户端收到后,用自己的密钥对其进行对称解密,得到服务器返回的数据。

13. 说说HTTP的状态码,301和302的区别?

302和301都有重定向的含义,但是它们也是有区别的。

  • 301:(永久性转移)请求的网页已被永久移动到新位置。服务器返回此响应时,会自动将请求者转到新位置。
  • 302:(暂时性转移)服务器目前正从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。此代码与响应GET和HEAD请求的301代码类似,会自动将请求者转到不同的位置。

网上有个很形象的例子比喻:

当一个网站或者网页24—48小时内临时移动到一个新的位置,这时候就要进行302跳转,打个比方说,我有一套房子,但是最近走亲戚去亲戚家住了,过两天我还回来的。而使用301跳转的场景就是之前的网站因为某种原因需要移除掉,然后要到新的地址访问,是永久性的,就比如你的那套房子其实是租的,现在租期到了,你又在另一个地方找到了房子,之前租的房子不住了。

14. 说说什么是数字签名?什么是数字证书?

数字证书是指在互联网通讯中标志通讯各方身份信息的一个数字认证,人们可以在网上用它来识别对方的身份。它的出现,是为了避免身份被篡改冒充的。比如Https的数字证书,就是为了避免公钥被中间人冒充篡改:

数字证书构成

  • 公钥和个人等信息,经过Hash摘要算法加密,形成消息摘要;将消息摘要拿到拥有公信力的认证中心(CA),用它的私钥对消息摘要签名,形成数字签名
  • 公钥和个人信息、数字签名共同构成数字证书

15. 对称加密与非对称加密有什么区别

对称加密:指加密和解密使用同一密钥,优点是运算速度较快,缺点是密钥分发。常见的对称加密算法有:DES、AES等。

非对称加密:指的是加密和解密使用不同的密钥(即公钥和私钥)。公钥与私钥是成对存在的,如果用公钥对数据进行加密,只有对应的私钥才能解密。常见的非对称加密算法有RSA ECC。

16. 说说DNS的解析过程?

DNS,英文全称是domain name system,域名解析系统,是Internet上作为域名和IP相互映射的一个分布式数据库。它的作用很明确,就是可以根据域名查出对应的IP地址。在浏览器缓存、本地DNS服务器、根域名服务器都是怎么查找的,大家回答的时候都可以说下哈。

DNS的解析过程如下图:

请添加图片描述

假设你要查询www.baidu.com的IP地址:

  • 首先会查找浏览器的缓存,看看是否能找到www.baidu.com对应的IP地址,找到就直接返回;否则进行下一步。
  • 将请求发往给本地DNS服务器,如果查找到也直接返回,否则继续进行下一步;
  • 本地DNS服务器向根域名服务器发送请求,根域名服务器返回负责.com的顶级域名服务器的IP地址的列表。
  • 本地DNS服务器再向其中一个负责.com的顶级域名服务器发送一个请求,返回负责.baidu的权威域名服务器的IP地址列表。
  • 本地DNS服务器再向其中一个权威域名服务器发送一个请求,返回www.baidu.com所对应的IP地址。

17. 什么是CSRF攻击,如何避免

什么是CSRF 攻击?

CSRF,跨站请求伪造(英文全称是Cross-site request forgery),是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。

CSRF是如何攻击的呢?

来看一个来自百度百科的例子哈:

请添加图片描述

  1. Tom 登陆银行,没有退出,浏览器包含了Tom在银行的身份认证信息。
  2. 黑客Jerry将伪造的转账请求,包含在帖子
  3. Tom在银行网站保持登陆的情况下,浏览帖子
  4. 黑客将伪造的转账请求连同身份认证信息,发送到银行网站
  5. 银行网站看到身份认证信息,以为就是Tom的合法操作,最后造成Tom资金损失。

CSRF攻击过程的受害者用户登录网站A,输入个人信息,在本地保存服务器生成的cookie。攻击者构建一条恶意链接,例如对受害者在网站A的信息及状态进行操作,典型的例子就是转账。受害者打开了攻击者构建的网页B,浏览器发出该恶意连接的请求,浏览器发起会话的过程中发送本地保存的cookie到网址A,A网站收到cookie,以为此链接是受害者发出的操作,导致受害者的身份被盗用,完成攻击者恶意的目的。

怎么解决CSRF攻击呢?

对于CSRF攻击,我们可以做如下防范:

(1) 验证码。应用程序和用户进行交互过程中,特别是账户交易这种核心步骤,强制用户输入验证码,才能完成最终请求。在通常情况下,验证码够很好地遏制CSRF攻击。但增加验证码降低了用户的体验,网站不能给所有的操作都加上验证码。所以只能将验证码作为一种辅助手段,在关键业务点设置验证码。

(2) Referer Check。HTTP Referer是header的一部分,当浏览器向web服务器发送请求时,一般会带上Referer信息告诉服务器是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。可以通过检查请求的来源来防御CSRF攻击。正常请求的referer具有一定规律,如在提交表单的referer必定是在该页面发起的请求。所以通过检查http包头referer的值是不是这个页面,来判断是不是CSRF攻击。**但在某些情况下如从https跳转到http,浏览器处于安全考虑,不会发送referer,服务器就无法进行check了。**若与该网站同域的其他网站有XSS漏洞,那么攻击者可以在其他网站注入恶意脚本,受害者进入了此类同域的网址,也会遭受攻击。出于以上原因,无法完全依赖Referer Check作为防御CSRF的主要手段。但是可以通过Referer Check来监控CSRF攻击的发生。

(3) Anti CSRF Token。目前比较完善的解决方案是加入Anti-CSRF-Token,即发送请求时在HTTP 请求中以参数的形式加入一个随机产生的token,并在服务器建立一个拦截器来验证这个token。

18. 聊聊五层计算机网络体系结构中,每一层对应的网络协议有哪些?

请添加图片描述

19.说说 WebSocket与socket的区别

  • Socket其实就是等于IP地址 + 端口 + 协议。 网络中的 Socket 并不是什么协议,而是为了使用 TCP,UDP 而抽象出来的一层 API,它是位于应用层和传输层之间的一个抽象层。具体来说,Socket是一套标准,它完成了对TCP/IP的高度封装,屏蔽网络细节,以方便开发者更好地进行网络编程。

  • 在这里插入图片描述在这里插入图片描述
    Socket编程:服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
    详见:Socket原理详解

  • WebSocket,即 Web 浏览器与 Web 服务器之间全双工通信标准。WebSocket与HTTP一样,都属于应用层协议。我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?答案很简单,因为 HTTP 协议有一个缺陷:通信只能由客户端发起。举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。WebSocket的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话。**客户端与服务器之间只需完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。**由于是建立在 HTTP 基础上的协议,因此连接的发起方仍是客户端,而一旦确立 WebSocket 通信连接,不论服务器还是客户端,任意一方都可直接向对方发送报文。

    WebSocket 是长轮询。具体比如在一个电商场景,商品的库存可能会变化,所以需要及时反映给用户,所以客户端会不停的发请求,然后服务器端会不停的去查变化,不管变不变,都返回,这个是短轮询。而长轮询则表现为如果没有变,就不返回,而是等待变或者超时(一般是十几秒)才返回,如果没有返回,客户端也不需要一直发请求,所以减少了双方的压力。

  • Socket 是传输控制层的接口。用户可以通过 Socket 来操作底层 TCP/IP 协议族通信。 Socket一个是网编编程的标准接口,而WebSocket则是应用层通信协议。 Socket 更灵活,更底层

20. 什么是DoS、DDoS、DRDoS攻击?

  • DOS: (Denial of Service),翻译过来就是拒绝服务,一切能引起DOS行为的攻击都被称为DOS攻击。最常见的DoS攻击就有计算机网络宽带攻击连通性攻击
  • DDoS: (Distributed Denial of Service),翻译过来是分布式拒绝服务。是指处于不同位置的多个攻击者同时向一个或几个目标发动攻击,或者一个攻击者控制了位于不同位置的多台机器并利用这些机器对受害者同时实施攻击。常见的DDos有SYN Flood、Ping of Death、ACK Flood、UDP Flood等。
  • DRDoS: (Distributed Reflection Denial of Service),中文是分布式反射拒绝服务,该方式靠的是发送大量带有被害者IP地址的数据包给攻击主机,然后攻击主机对IP地址源做出大量回应,从而形成拒绝服务攻击。

21. 什么是XSS攻击,如何避免?

XSS,叫跨站脚本攻击(Cross-Site Scripting),因此有人将跨站脚本攻击缩写为XSS。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意攻击用户的特殊目的。导致用户安全信息泄露(获取用户的敏感信息),危害数据安全。例如盗取各类用户帐号、网站挂马、盗窃企业重要信息等。

XSS主要分为两大类:非持久型攻击、持久型攻击。

  • 非持久型攻击(反射型XSS, DOM-based 型):经过后端,不经过数据库;
  • 持久型攻击(存储型XSS):经过后端,经过数据库。

常见的 XSS 攻击有三种:反射型、DOM-based 型、存储型。

持久型攻击 存储型XSS

持久型也可认为是存储型XSS:当恶意的代码写入web页面,会被存储到应用服务器端,简而言之就是会被存储到数据库。等用户再次打开web页面时,页面会继续执行恶意代码,达到持续攻击用户的作用。

攻击者事先将恶意代码上传或储存到漏洞服务器中,只要受害者浏览包含此恶意代码的页面就会执行恶意代码。这就意味着只要访问了这个页面的访客,都有可能会执行这段恶意脚本,因此储存型XSS的危害会更大。

存储型 XSS 一般出现在**网站留言、评论、博客日志等交互处**,恶意脚本存储到客户端或者服务端的数据库中。

2.非持久型攻击

(1)反射性XSS

非持久型XSS又叫反射型XSS,属于一次性攻击,仅对当次的页面访问产生影响。

反射型 XSS 一般是攻击者通过特定手法(如电子邮件),诱使用户去访问一个包含恶意代码的 URL,当受害者点击这些专门设计的链接的时候,恶意代码会直接在受害者主机上的浏览器执行,从而达到攻击目的.

对于访问者而言是一次性的,具体表现在我们把我们的恶意脚本通过 URL 的方式传递给了服务器,而服务器则只是不加处理的把脚本“反射”回访问者的浏览器而使访问者的浏览器执行相应的脚本。反射型 XSS 的触发有后端的参与,要避免反射性 XSS,必须需要后端的协调,后端解析前端的数据时首先做相关的字串检测和转义处理。

此类 XSS 通常出现在网站的搜索栏、用户登录口等地方,常用来窃取客户端 Cookies 或进行钓鱼欺骗。

(2)DOM-based 型

DOM是一个平台和语言都中立的接口,可以执行程序和脚本,能够动态访问和更新文档的内容、结构以及样式。DOM型XSS是一种特殊类型的反射型XSS,它是基于DOM文档对象模型的一种漏洞。DOM-xss是通过url传入参数去控制触发的。

客户端的脚本程序可以动态地检查和修改页面内容,而不依赖于服务器端的数据。例如客户端如从 URL 中提取数据并在本地执行,如果用户在客户端输入的数据包含了恶意的 JavaScript 脚本,而这些脚本没有经过适当的过滤和消毒,那么应用程序就可能受到 DOM-based XSS 攻击。需要特别注意以下的用户输入源 document.URL、 location.hash、 location.search、 document.referrer 等。
21.1 XSS是如何攻击的呢?

拿反射型举个例子吧,流程图如下:

请添加图片描述

21.2 如何解决XSS攻击问题?

xss漏洞在web站点运用中是最为常见的漏洞之一,XSS会以各种方式执行恶意的代码来破坏用户使用的站点。我们能够修补XSS漏洞,但是我们也不能100%的肯定没有人可以打破我们的过滤机制。恶意的攻击者总能够找到办法,绕过我们的过滤机制,从而进行恶意代码的执行。

1. 在web页面上,将用户输入的数据都进行转译,也就是将常用的恶意代码中的[<,>,”,,&]等符号都用[<,>,",&]字符进行转译。当这些html标签符号被转译后,浏览器就会拿它当作一个普通字符串对待,而不是当作一个标签的开始/结束标志对待。从而不会执行恶意代码。

2. DOM型XSS的防御方法:DOM型XSS主要是由客户端的脚本通过DOM动态数据输入到页面,而不是依赖于将数据提交给服务器端,从客户端获得DOM中的数据在本地执行。因而,仅从服务器端是无法防御的。其防御在于:
(1) 避免客户端文档重写、重定向或其他敏感操作;同时,避免使用客户端数据,这些操作尽量在服务器端使用动态页面来实现;
(2) 分析和强化客户端JS代码;特别是受到用户影响的DOM文档对象模型,注意能直接修改DOM和创建HTML文件的相关函数或方法,并在输出变量到页面时先进行编码转义,如输出到HTML则进行HTML编码、输出到<>则进行JS编码。

获取用户的输入,不用innerHtml,用innerText.
对用户的输入进行过滤,如对& < > " ' /等进行转义 
限制输入长度 
对于链接跳转,如` 等,要校验内容,禁止以script开头的非法链接。
  • 对输入进行过滤,过滤标签等,只允许合法值。
  • HTML转义
  • 对于链接跳转,如` 等,要校验内容,禁止以script开头的非法链接。
  • 限制输入长度

22. Http请求的过程与原理

HTTP是一个基于TCP/IP协议来传递数据的超文本传输协议,传输的数据类型有HTML,图片等。以访问百度为例子,看下一次Http的请求过程吧

Http请求过程

  1. 客户端进行DNS域名解析,得到对应的IP地址
  2. 根据这个IP,找到对应的服务器建立连接(三次握手)
  3. 建立TCP连接后发起HTTP请求(一个完整的http请求报文)
  4. 服务器响应HTTP请求,客户端得到html代码
  5. 客户端解析html代码,用html代码中的资源(如js,css,图片等等)渲染页面。
  6. 服务器关闭TCP连接(四次挥手)

23. forward和redirect的区别?

forward是转发,redirect是重定向。

我的答案如下

  • 直接转发方式(Forward) ,客户端和浏览器只发出一次请求,Servlet、HTML、JSP或其它信息资源,由第二个信息资源响应该请求,在请求对象request中,保存的对象对于每个信息资源是共享的。 forword是服务器内部的重定向,服务器直接访问目标地址的 url网址,把里面的东西读取出来,但是客户端并不知道,因此用forward的话,客户端浏览器的网址是不会发生变化的。
  • 间接转发方式(Redirect) 实际是两次HTTP请求,服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。 redirect是服务器根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,所以地址栏显示的是新的地址。
  • 直接转发就相当于:“A找B借钱,B说没有,B去找C借,借到借不到都会把消息传递给A”;
  • 间接转发就相当于:“A找B借钱,B说没有,让A去找C借”。

forword 一般用于用户登录的时候,根据角色转发到相应的模块,redirect一般用于用户注销登录时返回主页面或者跳转到其他网站

forword效率高,而redirect效率低

forword转发是服务器上的行为,而redirect重定向是客户端的行为

24. 聊聊SQL注入?

SQL注入是一种代码注入技术,一般被应用于攻击web应用程序。它通过在web应用接口传入一些特殊参数字符,来欺骗应用服务器,执行恶意的SQL命令,以达到非法获取系统信息的目的。它目前是黑客对数据库进行攻击的最常用手段之一。

24.1 SQL注入是如何攻击的?

举个常见的业务场景:在web表单搜索框输入员工名字,然后后台查询出对应名字的员工。这种场景下,一般都是前端页面,把一个名字参数name传到后台,然后后台通过SQL把结果查询出来

name = "田螺"; // 前端传过来的SQL= "select * from staff where name=" + name;  // 根据前端传过来的name参数,查询数据库员工表staff

因为SQL是直接拼接的,如果我们完全信任前端传的参数的话。假如前端传这么一个参数时'' or '1'='1',SQL就变成

select * from staff where name='' or '1'='1';

这个SQL会把所有的员工信息全都查出来了,请求用户已经越权啦。请求者可以获取所有员工的信息,信息已经暴露。
Java解决SQL注入问题

24.2 如何预防SQL注入问题

1). 不要暴露一些不必要的日志或者安全信息,比如避免直接响应一些sql异常信息。

如果SQL发生异常了,不要把这些信息暴露响应给用户,可以自定义异常进行响应

2). 不相信任何外部输入参数,过滤参数中含有的一些数据库关键词关键词

可以加个参数校验过滤的方法,过滤union,or等数据库关键词

3). 适当的权限控制

在你查询信息时,先校验下当前用户是否有这个权限。比如说,实现代码的时候,可以让用户多传一个企业Id什么的,或者获取当前用户的session信息等,在查询前,先校验一下当前用户是否是这个企业下的等等,是的话才有这个查询员工的权限。

25. Session和Cookie的区别。

我们先来看Session和Cookie的概念吧:

  • Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
  • Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session,向用户返回session id。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。

Session 和Cookie的区别主要有这些:

请添加图片描述
Session、Cookie、Token的联系
来看个图吧:

请添加图片描述

  • 用户第一次请求服务器时,服务器根据用户提交的信息,创建对应的Session,请求返回时将此Session的唯一标识信息SessionID返回给浏览器,浏览器接收到服务器返回的SessionID信息后,会将此信息存入Cookie中,同时Cookie记录此SessionID是属于哪个域名。
  • 当用户第二次访问服务器时,请求会自动判断此域名下是否存在Cookie信息,如果存在,则自动将Cookie信息也发送给服务端,服务端会从Cookie中获取SessionID,再根据 SessionID查找对应的 Session信息,如果没有找到,说明用户没有登录或者登录失效,如果找到Session证明用户已经登录可执行后面操作。

26. IP地址有哪些分类?

一般可以这么认为,IP地址 = 网络号+主机号。

  1. 网络号:它标志主机所连接的网络地址表示属于互联网的哪一个网络。
  2. 主机号:它标志主机地址表示其属于该网络中的哪一台主机。

IP地址分为A,B,C,D,E五大类:

  • A类地址(1~126):以0开头,网络号占前8位,主机号占后面24位。
  • B类地址(128~191):以10开头,网络号占前16位,主机号占后面16位。
  • C类地址(192~223):以110开头,网络号占前24位,主机号占后面8位。
  • D类地址(224~239):以1110开头,保留位多播地址。
  • E类地址(240~255):以11110开头,保留位为将来使用

请添加图片描述

27. 说下ARP 协议的工作过程?

ARP 协议协议,Address Resolution Protocol,地址解析协议,它是用于实现IP地址到MAC地址的映射。

  1. 首先,每台主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址的对应关系。

    1. 当源主机需要将一个数据包要发送到目的主机时,会首先检查自己的ARP列表,是否存在该IP地址对应的MAC地址;如果有,就直接将数据包发送到这个MAC地址;如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。此ARP请求的数据包里,包括源主机的IP地址、硬件地址、以及目的主机的IP地址。
  2. 网络中所有的主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致。如果不相同,就会忽略此数据包;如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个 ARP响应数据包,告诉对方自己是它需要查找的MAC地址。

    1. 源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息开始数据的传输。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。

28. 有了IP地址,为什么还要用MAC地址?

  • 简而言之,标识网络中的一台计算机,比较常用的就是IP地址和MAC地址,但计算机的IP地址可由用户自行更改,管理起来就相对困难,而MAC地址不可更改,所以一般会把IP地址和MAC地址组合起来使用。
  • 那只使用MAC地址不用IP地址行不行呢?不行的!因为最早就是MAC地址先出现的,并且当时并不用IP地址,只用MAC地址,后来随着网络中的设备越来越多,整个路由过程越来越复杂,便出现了子网的概念。对于目的地址在其他子网的数据包,路由只需要将数据包送到那个子网即可。
  • 那为什么要用IP地址呢?是因为IP地址是和地域相关的,对于同一个子网上的设备,IP地址的前缀都是一样的,这样路由器通过IP地址的前缀就知道设备在在哪个子网上了,而只用MAC地址的话,路由器则需要记住每个MAC地址在哪个子网,这需要路由器有极大的存储空间,是无法实现的。
  • IP地址可以比作为地址,MAC地址为收件人,在一次通信过程中,两者是缺一不可的。

29. TCP 和 UDP 分别对应的常见应用层协议有哪些?

基于TCP的应用层协议有:HTTP、FTP、SMTP、TELNET、SSH

  • HTTP:HyperText Transfer Protocol(超文本传输协议),默认端口80
  • FTP: File Transfer Protocol (文件传输协议), 默认端口(20用于传输数据,21用于传输控制信息)
  • SMTP: Simple Mail Transfer Protocol (简单邮件传输协议) ,默认端口25
  • TELNET: Teletype over the Network (网络电传), 默认端口23
  • SSH:Secure Shell(安全外壳协议),默认端口 22

基于UDP的应用层协议:DNS、TFTP、SNMP

  • DNS : Domain Name Service (域名服务),默认端口 53
  • TFTP: Trivial File Transfer Protocol (简单文件传输协议),默认端口69
  • SNMP:Simple Network Management Protocol(简单网络管理协议),通过UDP端口161接收,只有Trap信息采用UDP端口162。

30. 聊聊保活计时器的作用

除时间等待计时器外,TCP 还有一个保活计时器(keepalive timer)。设想这样的场景:客户已主动与服务器建立了TCP连接。但后来客户端的主机突然发生故障。显然,服务器以后就不能再收到客户端发来的数据。因此,应当有措施使服务器不要再白白等待下去。这就需要使用保活计时器了。

服务器每收到一次客户的数据,就重新设置保活计时器,时间的设置通常是两个小时。若两个小时都没有收到客户端的数据,服务端就发送一个探测报文段,以后则每隔 75秒钟发送一次。若连续发送10个探测报文段后仍然无客户端的响应,服务端就认为客户端出了故障,接着就关闭这个连接。

31. 如果服务器出现了大量CLOSE_WAIT状态如何解决。

我们先来复习下TCP的四次挥手

请添加图片描述

  • 服务器端收到客户端发送的FIN后,TCP协议栈就会自动发送ACK,接着进入CLOSE_WAIT状态。
  • 但是如果服务器端不执行socket的close()操作,那么就没法进入LAST_ACK,导致大量连接处于CLOSE_WAIT状态
  • 所以,如果服务器出现了大量CLOSE_WAIT状态,一般是程序Bug,或者关闭socket不及时。 大量socket的fd被占用,这个是有上限的,超过了就不能接受新的连接了。

32. URI和URL的区别

  • URI,全称是Uniform Resource Identifier),中文翻译是统一资源标志符,主要作用是唯一标识一个资源
  • URL,全称是Uniform Resource Location),中文翻译是统一资源定位符,主要作用是提供资源的路径
  • 打个经典比喻吧,URI像是身份证,可以唯一标识一个人,而URL更像一个住址,可以通过URL找到这个人。

33. ICMP协议的功能

ICMP,(Internet Control Message Protocol) ,Internet控制消息协议。

  • ICMP协议是一种面向无连接的协议,用于传输出错报告控制信息。
  • 它是一个非常重要的协议,它对于网络安全具有极其重要的意义。它属于网络层协议,主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。
  • 当遇到IP数据无法访问目标、IP路由器无法按当前的传输速率转发数据包等情况时,会自动发送ICMP消息。

比如我们日常使用得比较多的ping,就是基于ICMP的。

34. 说下ping的原理

ping,Packet Internet Groper,是一种因特网包探索器,用于测试网络连接量的程序。Ping是工作在TCP/IP网络体系结构中应用层的一个服务命令, 主要是向特定的目的主机发送ICMP(Internet Control Message Protocol 因特网报文控制协议) 请求报文,测试目的站是否可达及了解其有关状态

一般来说,ping可以用来检测网络通不通。它是基于ICMP协议工作的。假设机器Aping机器B,工作过程如下:

  1. ping通知系统,新建一个固定格式的ICMP请求数据包
  2. ICMP协议,将该数据包和目标机器B的IP地址打包,一起转交给IP协议层
  3. IP层协议将本机IP地址为源地址,机器B的IP地址为目标地址,加上一些其他的控制信息,构建一个IP数据包
  4. 先获取目标机器B的MAC地址。
  5. 数据链路层构建一个数据帧,目的地址是IP层传过来的MAC地址,源地址是本机的MAC地址
  6. 机器B收到后,对比目标地址,和自己本机的MAC地址是否一致,符合就处理返回,不符合就丢弃。
  7. 根据目的主机返回的ICMP回送回答报文中的时间戳,从而计算出往返时间
  8. 最终显示结果有这几项:发送到目的主机的IP地址、发送 & 收到 & 丢失的分组数、往返时间的最小、最大& 平均值

36. 请详细介绍一下TCP 的三次握手机制

参考
TCP提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的就是同步连接双方的序列号和确认号并交换TCP窗口大小信息。我们一起来看下流程图哈:
在这里插入图片描述
1, TCP服务器进程先创建传输控制块TCB(可以理解为Socket), 时刻准备接受客户端进程的连接请求, 此时服务器就进入了 LISTEN(监听)状态
2, TCP客户端进程也是先创建传输控制块TCB, 然后向服务器发出连接请求报文,此时报文首部中的同步标志位SYN=1, 同时选择一个初始序列号 seq = x, 此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定, SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
3, TCP服务器收到请求报文后, 如果同意连接, 则发出确认报文。确认报文中的 ACK=1, SYN=1, 确认序号是 x+1, 同时也要为自己初始化一个序列号 seq = y, 此时, TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据, 但是同样要消耗一个序号。
4, TCP客户端进程收到确认后还, 要向服务器给出确认。确认报文的ACK=1,确认序号是 y+1,自己的序列号是 x+1.
5, 此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。

  • 第一次握手(SYN=1, seq=x),发送完毕后,客户端就进入SYN_SEND状态
  • 第二次握手(SYN=1, ACK=1, seq=y,ack=x+1), 发送完毕后,服务器端就进入SYN_RCV状态。
  • 第三次握手(ACK=1,ack=y+1),发送完毕后,客户端进入ESTABLISHED状态,当服务器端接收到这个包时,也进入ESTABLISHED状态。

37. TCP握手为什么是三次,为什么不能是两次?不能是四次?

思路: TCP握手为什么不能是两次,为什么不能是四次呢?为了方便理解,我们以男孩子和女孩子谈恋爱为例子:两个人能走到一起,最重要的事情就是相爱,就是我爱你,并且我知道,你也爱我,接下来我们以此来模拟三次握手的过程:

请添加图片描述

为什么握手不能是两次呢?
主要是为了防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送的第一个请求连接并且没有丢失,只是因为在网络中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时之前滞留的那一次请求连接,因为网络通畅了, 到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的费。
如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。
简单来说就是无法确认客户端的接收能力。

为什么握手不能是四次呢?

因为握手不能是四次呢?因为三次已经够了,三次已经能让双方都知道:你爱我,我也爱你。而四次就多余了。四次以上都可以,只不过 三次就够了

38. 说说TCP四次挥手过程

请添加图片描述

  1. 第一次挥手(FIN=1,seq=u),发送完毕后,客户端进入FIN_WAIT_1状态。
  2. 第二次挥手(ACK=1,ack=u+1,seq =v),发送完毕后,服务器端进入CLOSE_WAIT状态,客户端接收到这个确认包之后,进入FIN_WAIT_2状态。
  3. 第三次挥手(FIN=1,ACK1,seq=w,ack=u+1),发送完毕后,服务器端进入LAST_ACK状态,等待来自客户端的最后一个ACK。
  4. 第四次挥手(ACK=1,seq=u+1,ack=w+1),客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入TIME_WAIT状态,等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入CLOSED状态。服务器端接收到这个确认包之后,关闭连接,进入CLOSED状态。

39. TCP挥手为什么需要四次呢?

思路: TCP挥手为什么需要四次呢?为了方便大家理解,再举个生活的例子吧。

小明和小红打电话聊天,通话差不多要结束时,小红说,“我没啥要说的了”。小明回答,“我知道了”。但是小明可能还有要说的话,小红不能要求小明跟着她自己的节奏结束通话,于是小明可能又叽叽歪歪说了一通,最后小明说,“我说完了”,小红回答,“我知道了”,这样通话才算结束。

如果是三次的话,那么服务端的 ACK 和 FIN 合成一个挥手,那么长时间的延迟可能让 TCP 以为FIN 没有达到服务器端,然后让客户端不断的重发 FIN 。

40. TCP四次挥手过程中,为什么需要等待2MSL,才进入CLOSED关闭状态

2MSL,two Maximum Segment Lifetime,即两个最大段生命周期。假设主动发起挥手的是客户端,那么需要2MSL的原因是:

  • 1.为了保证客户端发送的最后一个ACK报文段能够到达服务端。 这个ACK报文段有可能丢失,处在LAST-ACK状态的服务端就收不到对已发送的FIN + ACK报文段的确认。服务端会超时重传这个FIN+ACK 报文段,而客户端就能在 2MSL 时间内(超时 + 1MSL 传输)收到这个重传的 FIN+ACK 报文段。接着客户端重传一次确认,重新启动2MSL计时器。最后,客户端和服务器都正常进入到CLOSED状态。
  • 2. 防止已失效的连接请求报文段出现在本连接中。客户端在发送完最后一个ACK报文段后,再经过时间2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个连接中不会出现这种旧的连接请求报文段。

41. TCP的粘包和拆包

TCP是面向流,没有界限的一串数据。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。

请添加图片描述

为什么会产生粘包和拆包呢?

  • 要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包;
  • 接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包;
  • 要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包;
  • 待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。即TCP报文长度-TCP头部长度>MSS。

解决方案:

  • 发送端将每个数据包封装为固定长度
  • 在数据尾部增加特殊字符进行分割
  • 将数据分为两部分,一部分是头部,一部分是内容体;其中头部结构大小固定,且有一个字段声明内容体的大小。

42. 聊聊TCP的流量控制

TCP三次握手,发送端和接收端进入到ESTABLISHED状态,它们即可以愉快地传输数据啦。但是发送端不能疯狂地向接收端发送数据,因为接收端接收不过来的话,接收方只能把处理不过来的数据存在缓存区里。如果缓存区都满了,发送方还在疯狂发送数据的话,接收方只能把收到的数据包丢掉,这就浪费了网络资源啦。

TCP 提供一种机制可以让发送端根据接收端的实际接收能力控制发送的数据量,这就是流量控制

TCP通过滑动窗口来控制流量,我们看下流量控制的简要流程吧:

首先双方三次握手,初始化各自的窗口大小,均为 400 个字节。

请添加图片描述

TCP的流量控制

  1. 假如当前发送方给接收方发送了200个字节,那么,发送方的SND.NXT会右移200个字节,也就是说当前的可用窗口减少了200 个字节。
  2. 接受方收到后,放到缓冲队列里面,REV.WND =400-200=200字节,所以win=200字节返回给发送方。接收方会在 ACK 的报文首部带上缩小后的滑动窗口200字节
  3. 发送方又发送200字节过来,200字节到达,继续放到缓冲队列。不过这时候,由于大量负载的原因,接受方处理不了这么多字节,只能处理100字节,剩余的100字节继续放到缓冲队列。这时候,REV.WND = 400-200-100=100字节,即win=100返回发送方。
  4. 发送方继续干活,发送100字节过来,这时候,接受窗口win变为0。
  5. 发送方停止发送,开启一个定时任务,每隔一段时间,就去询问接受方,直到win大于0,才继续开始发送。

43. 说说半连接队列和 SYN Flood攻击的关系

TCP进入三次握手前,服务端会从CLOSED状态变为LISTEN状态,同时在内部创建了两个队列:半连接队列(SYN队列)和全连接队列(ACCEPT队列)。

什么是半连接队列(SYN队列) 呢? 什么是全连接队列(ACCEPT队列) 呢?回忆下TCP三次握手的图:

请添加图片描述

  • TCP三次握手时,客户端发送SYN到服务端,服务端收到之后,便回复ACK和SYN,状态由LISTEN变为SYN_RCVD,此时这个连接就被推入了SYN队列,即半连接队列。
  • 当客户端回复ACK, 服务端接收后,三次握手就完成了。这时连接会等待被具体的应用取走,在被取走之前,它被推入ACCEPT队列,即全连接队列。

SYN Flood是一种典型的DDos攻击,它在短时间内,伪造不存在的IP地址,向服务器大量发起SYN报文。当服务器回复SYN+ACK报文后,不会收到ACK回应报文,导致服务器上建立大量的半连接半连接队列满了,这就无法处理正常的TCP请求啦。

那么有哪些方案应对呢?主要有 syn cookieSYN Proxy防火墙等。

  • syn cookie:在收到SYN包后,服务器根据一定的方法,以数据包的源地址、端口等信息为参数计算出一个cookie值作为自己的SYN ACK包的序列号,回复SYN+ACK后,服务器并不立即分配资源进行处理,等收到发送方的ACK包后,重新根据数据包的源地址、端口计算该包中的确认序列号是否正确,如果正确则建立连接,否则丢弃该包。
  • SYN Proxy防火墙:服务器防火墙会对收到的每一个SYN报文进行代理和回应,并保持半连接。等发送方将ACK包返回后,再重新构造SYN包发到服务器,建立真正的TCP连接。

44. 聊聊TCP的滑动窗口

TCP报文首部有个字段win控制窗口大小的,同时也需要掌握,滑动窗口是怎么滑的。TCP 发送一个数据,如果需要收到确认应答,才会发送下一个数据。这样的话就会有个缺点:效率会比较低。

这就好像我们面对面在聊天,你说完一句,我应答之后,你才能说下一句。那么,如果我在忙其他事情,没有能够及时回复你呢?你说完一句后,要等到我忙完回复你,你才说下句,这显然不现实,效率太低。

为了解决这个问题,TCP引入了窗口,它是操作系统开辟的一个缓存空间。窗口大小值表示无需等待确认应答,而可以继续发送数据的最大值。

TCP头部有个字段叫win,它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度,从而达到流量控制的目的。

通俗点讲,就是接受方每次收到数据包,在发送确认报文的时候,同时告诉发送方,自己的缓存区还有多少空余空间,缓冲区的空余空间,我们就称之为接受窗口大小。这就是win。

TCP 滑动窗口分为两种: 发送窗口和接收窗口。发送端的滑动窗口包含四大部分,如下:

  • 已发送且已收到ACK确认
  • 已发送但未收到ACK确认
  • 未发送但可以发送
  • 未发送也不可以发送

请添加图片描述

  • 虚线矩形框,就是发送窗口。
  • SND.WND: 表示发送窗口的大小,上图虚线框的格子数是14个,即发送窗口大小是14。
  • SND.NXT:下一个发送的位置,它指向未发送但可以发送的第一个字节的序列号。
  • SND.UNA: 一个绝对指针,它指向的是已发送但未确认的第一个字节的序列号。

接收方的滑动窗口包含三大部分,如下:

  • 已成功接收并确认
  • 未收到数据但可以接收
  • 未收到数据并不可以接收的数据

请添加图片描述

  • 虚线矩形框,就是接收窗口。
  • REV.WND: 表示接收窗口的大小,上图虚线框的格子就是9个。
  • REV.NXT:下一个接收的位置,它指向未收到但可以接收的第一个字节的序列号。

45. TCP的拥塞控制

思路讲解: TCP拥塞机制也是个高频考点,需要掌握它跟流量控制的区别,也需要掌握拥塞控制的这几种算法:慢启动算法、拥塞避免、拥塞发生、快速恢复算法

拥塞控制是作用于网络的,防止过多的数据包注入到网络中,避免出现网络负载过大的情况。它的目标主要是最大化利用网络上瓶颈链路的带宽。它跟流量控制又有什么区别呢?

流量控制是作用于接收者的,根据接收端的实际接收能力控制发送速度,防止分组丢失的。

我们可以把网络链路比喻成一根水管,如果我们想最大化利用网络来传输数据,那就是尽快让水管达到最佳充满状态。

请添加图片描述

发送方维护一个拥塞窗口cwnd(congestion window) 的变量,用来估算在一段时间内这条链路(水管)可以承载和运输的数据(水)的数量。它大小代表着网络的拥塞程度,并且是动态变化的,但是为了达到最大的传输效率,我们该如何知道这条水管的运送效率是多少呢?

一个比较简单的方法就是不断增加传输的水量,直到水管快要爆裂为止(对应到网络上就是发生丢包),用 TCP的描述就是:

只要网络中没有出现拥塞,拥塞窗口的值就可以再增大一些,以便把更多的数据包发送出去,但只要网络出现拥塞,拥塞窗口的值就应该减小一些,以减少注入到网络中的数据包数。其实只要「发送⽅」没有在规定时间内接收到 ACK 应答报⽂,也就是发⽣了超时重传,就会认为⽹络出现了拥塞

实际上,拥塞控制主要有这几种常用算法

  • 慢启动
  • 拥塞避免
  • 拥塞发生
  • 快速恢复
45.1 慢启动算法

慢启动算法,表面意思就是,别急慢慢来。它表示TCP建立连接完成后,一开始不要发送大量的数据,而是先探测一下网络的拥塞程度。由小到大逐渐增加拥塞窗口的大小,如果没有出现丢包,当发送⽅每收到⼀个 ACK,拥塞窗⼝cwnd的⼤⼩就会加1。

  • TCP连接完成,初始化cwnd = 1,表明可以传一个MSS单位大小的数据。
  • 当收到⼀个 ACK 确认应答后,cwnd 增加 1,于是⼀次能够发送 2 个 ,当收到 2 个的 ACK 确认应答后, cwnd 增加 2,于是就可以⽐之前多发2 个,所以这⼀次能够发送 4 个 ,当这 4 个的 ACK 确认到来的时候,每个确认 cwnd 增加 1, 4 个确认 cwnd 增加 4,于是就可以⽐之前多发4 个,所以这⼀次能够发送 8 个。
  • 可以看出慢启动算法,发包的个数是指数性的增⻓

请添加图片描述

为了防止cwnd增长过大引起网络拥塞,还需设置一个慢启动阀值ssthresh(slow start threshold)状态变量。当cwnd >ssthresh时,进入了拥塞避免算法。

45.2 拥塞避免算法

一般来说,慢启动阀值ssthresh是65535字节,cwnd到达慢启动阀值

  • 每收到一个ACK时,cwnd = cwnd + 1/cwnd 每当收到⼀个ACK 时,cwnd 增加1/cwnd。

显然这是一个线性上升的算法,避免过快导致网络拥塞问题。当16个 ACK 应答确认到来时,每个确认增加 1/16,16 个 ACK 确认 cwnd ⼀共增加 1,于是这⼀次能够发送 17个 MSS ⼤⼩的数据,变成了线性增⻓。

请添加图片描述

拥塞避免算法就是将原本慢启动算法的指数增⻓变成了线性增⻓,还是增⻓阶段,但是增⻓速度缓慢了⼀些。 就这么⼀直增⻓着后,⽹络就会慢慢进⼊了拥塞的状况了,于是就会出现丢包现象,这时就需要对丢失的数据包进⾏重传。当触发了重传机制,也就进⼊了「拥塞发⽣算法」。

45.3 拥塞发生

当网络拥塞发生丢包时,会有两种情况:

  • RTO超时重传
  • 快速重传

如果是发生了RTO超时重传,就会使用拥塞发生算法

  • 慢启动阀值sshthresh = cwnd /2
  • cwnd 重置为 1
  • 进入新的慢启动过程

请添加图片描述

这真的是辛辛苦苦几十年,一朝回到解放前。其实还有更好的处理方式,就是快速重传。发送方收到3个连续重复的ACK时,就会快速地重传,不必等待RTO超时再重传。
请添加图片描述

45.4 快速恢复

快速重传和快速恢复算法一般同时使用。快速恢复算法认为,还有3个重复ACK收到,说明网络也没那么糟糕,所以没有必要像RTO超时那么强烈。

正如前面所说,进入快速恢复之前,cwnd 和 sshthresh已被更新:

cwnd = cwnd /2
sshthresh = cwnd

然后,真正的快速算法如下:

  • cwnd = sshthresh + 3 3 的意思是确认有 3 个数据包被收到了
  • 重传重复的那几个ACK(即丢失的那几个数据包)
  • 如果再收到重复的 ACK,那么 cwnd = cwnd +1
  • 如果收到新数据的 ACK 后, cwnd = sshthresh。因为收到新数据的 ACK,表明恢复过程已经结束,可以再次进入拥塞避免的算法了。

46.请简述TCP和UDP的区别

TCP是面向连接,而UDP是无连接

  • TCP 是面向连接的、可靠的、传输层通信协议
  • UDP 是无连接的传输层通信协议,继承 IP 特性,基于数据报

为什么 TCP 可靠?TCP 的可靠性体现在有状态和控制

  • 会精准记录那些数据发送了,那些数据被对方接收了,那些没有被接收,而且保证数据包按序到达,不允许半点差错,这就是有状态
  • 当意识到丢包了或者网络环境不佳,TCP 会根据具体情况调整自己的行为,控制自己的发送速度或者重发,这是可控制的

反之 UDP 就是无状态的和不可控制的

TCP和UDP对比
请添加图片描述

47. 说说TCP是如何确保可靠性的呢?

连接和断开的可靠性(三次握手,四次挥手)、有状态(哪些数据发送了,哪些没发)、可控制(超时重传、流量控制、拥塞控制等)。

  • 首先,TCP的连接是基于三次握手,而断开则是基于四次挥手。确保连接和断开的可靠性。
  • 其次,TCP的可靠性,还体现在有状态;TCP会记录哪些数据发送了,哪些数据被接收了,哪些没有被接受,并且保证数据包按序到达,保证数据传输不出差错。
  • 再次,TCP的可靠性,还体现在可控制。它有数据包校验、ACK应答、超时重传(发送方)、失序数据重传(接收方)、丢弃重复数据、流量控制(滑动窗口)和拥塞控制等机制。

48. 说说TCP报文首部有哪些字段,其作用又分别是什么?

思路: 小伙伴们,可以记下这个图。

请添加图片描述

  • 16位端口号:源端口号,主机该报文段是来自哪里;目标端口号,要传给哪个上层协议或应用程序
  • 32位序号:一次TCP通信(从TCP连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号。
  • 32位确认号:用作对另一方发送的tcp报文段的响应。其值是收到的TCP报文段的序号值加1。
  • 4位头部长度:表示tcp头部有多少个32bit字(4字节)。因为4位最大能标识15,所以TCP头部最长是60字节。
  • 6位标志位:URG(紧急指针是否有效),ACK(表示确认号是否有效),PSH(缓冲区尚未填满),RST(表示要求对方重新建立连接),SYN(建立连接消息标志接),FIN(表示告知对方本端要关闭连接了)
  • 16位窗口大小:是TCP流量控制的一个手段。这里说的窗口,指的是接收通告窗口。它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。
  • 16位校验和:由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。注意,这个校验不仅包括TCP头部,也包括数据部分。这也是TCP可靠传输的一个重要保障。
  • 16位紧急指针:一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。因此,确切地说,这个字段是紧急指针相对当前序号的偏移,不妨称之为紧急偏移。TCP的紧急指针是发送端向接收端发送紧急数据的方法。

49. Nagle 算法与延迟确认

49.1 Nagle算法

如果发送方疯狂地向接收方发送很小的数据包,比如一次就发送1个字节,那么显然会有问题。

TCP/IP协议中,无论发送多少数据,总是需要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认。为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。

Nagle算法:任意时刻,最多只能有一个未被确认的小段。所谓“小段”,指的是小于MSS尺寸的数据块,所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到。

Nagle算法的实现规则:

  • 如果包长度达到MSS,则允许发送;
  • 如果该包含有FIN,则允许发送;
  • 设置了TCP_NODELAY选项,则允许发送;
  • 未设置TCP_CORK选项时,若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送;
  • 上述条件都未满足,但发生了超时(一般为200ms),则立即发送。
49.2 延迟确认

如果接受方刚接收到发送方的数据包,在很短很短的时间内,又接收到第二个包。那么请问接收方是一个一个地回复好点,还是合在一起回复好呢?

接收方收到数据包后,如果暂时没有数据要发给对端,它可以等一小段时间,再确认(Linux上默认是40ms)。如果这段时间刚好有数据要传给对端,ACK就随着数据传输,而不需要单独发送一次ACK。如果超过时间还没有数据要发送,也发送ACK,避免对端以为丢包。

但是有些场景不能用延迟确认,比如发现了乱序包接收到了大于一个 frame 的报文,且需要调整窗口大小等。

一般情况下,Nagle算法和延迟确认不能一起使用,Nagle算法意味着延迟发,延迟确认意味着延迟接收,会造成更大的延迟,会产生性能问题。

50. 说说TCP的重传机制

重传包括超时重传、快速重传、带选择确认的重传(SACK)、重复SACK四种

50.1 超时重传

超时重传,是TCP协议保证数据可靠性的另一个重要机制,其原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止。这个一定时间内,一般是多少比较合理呢?来看下什么叫RTT(Round-Trip Time,往返时间)。RTT就是数据完全发送完,到收到确认信号的时间,即数据包的一次往返时间。超时重传时间,就是RTO(Retransmission Timeout)。

请添加图片描述

那么,RTO到底设置多大呢?

  • 如果RTO设置很大,等了很久都没重发,这样肯定就不行。
  • 如果RTO设置很小,那很可能数据都没有丢失,就开始重发了,这会导致网络阻塞,从而恶性循环,导致更多的超时出现。

一般来说,RTO略微大于RTT,效果是最佳的。其实,RTO有个标准方法的计算公式,也叫Jacobson / Karels 算法。一起来看下吧:

1. 首先计算SRTT(即计算平滑的RTT)

SRTT = (1 - α) * SRTT + α * RTT //求 SRTT 的加权平均

2. 其次,计算RTTVAR (round-trip time variation)

RTTVAR = (1 - β) * RTTVAR + β * (|RTT - SRTT|) //计算 SRTT 与真实值的差距

3. 最后,得出最终的RTO

RTO = µ * SRTT + ∂ * RTTVAR = SRTT + 4·RTTVAR

一般情况,α、β等的参数取值如下:

α = 0.125,β = 0.25, μ = 1,∂ = 4

别问这些参数是怎么来的,它们是大量实践,调出的最优参数。

超时重传不是十分完美的重传方案,它有这些缺点:

  • 当一个报文丢失时,会等待一定的超时周期,才重传分组,增加了端到端的时延。
  • 当一个报文丢失时,在其等待超时的过程中,可能会出现这种情况:其后的报文段已经被接收端接收但却迟迟得不到确认,发送端会认为也丢失了,从而引起不必要的重传,既浪费资源也浪费时间。

并且,对于TCP,如果发生一次超时重传,时间间隔下次就会加倍。

50.2 快速重传

其实可以使用快速重传,来解决超时重发的时间等待问题。它不以时间驱动,而是以数据驱动。它是基于接收端的反馈信息来引发重传的。快速重传流程如下:

请添加图片描述

发送方发送了 1,2,3,4,5,6份数据:

  • 第一份 Seq=1 先送到了,于是就 Ack回2;
  • 第二份 Seq=2 也送到了,于是ACK回3;
  • 第三份 Seq=3 由于网络等某些原因,没送到;
  • 第四份 Seq=4 送到了,但是由于Seq=3没收到。因此ACK还是回3;
  • 后面的 Seq=5,6的也送到了,ACK还是回复3,因为Seq=3没有收到。
  • 发送方连着收到三个重复冗余ACK=3的确认(其实是4个哈,但是因为前面的一个是正常的ACK,后面三个才是重复冗余的),于是知道3报文段在传输过程中丢失了;发送方在定时器过期之前,重传该报文段。
  • 最后,接收方收到了 Seq=3,此时因为 Seq=4,5,6都收到了,于是它回ACK=7。

但是呢,快速重传也可能有问题:ACK只向告知发送方,最大的有序报文段。到底是哪个报文丢失了呢?并不确定!那到底该重传多少个包呢?

是重传 Seq=3 ?还是重传 Seq=3、Seq=4、Seq=5、Seq=6 呢?因为发送端并不清楚这三个连续的 ACK=3 是谁传回来的。

50.3 带选择确认的重传(SACK)

为了解决:应该重传多少个包的问题? TCP提供了带选择确认的重传(即SACK,Selective Acknowledgment)。

SACK机制就是,在快速重传的基础上,接收方返回最近收到报文段的序列号范围,这样发送方就知道接收方哪些数据包是没收到的。这样就很清楚应该重传哪些数据包啦。

请添加图片描述

如上图中,发送方收到了三次同样的ACK=30的确认报文,于是就会触发快速重发机制,通过SACK信息发现只有30~39这段数据丢失,于是重发时,就只选择了这个30~39的TCP报文段进行重发。

50.4 重复SACK(D-SACK)

D-SACK,英文是Duplicate SACK,是在SACK的基础上做了一些扩展,主要用来告诉发送方,有哪些数据包,自己重复接受了。DSACK的目的是帮助发送方判断,是否发生了包失序、ACK丢失、包重复或伪重传。让TCP可以更好的做网络流控。来看个图吧:

ACK= 30 表示30没发送 SACK = 4050,告诉「发送⽅」4050 的数据早已被接收了
请添加图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我顶得了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值