柒夭日志:计算机网络

📚计算机网络基础


1. 请你简单说一下计算机网络的分层模型

计算机网络体系结构,一般有三种:OSI 七层模型、TCP/IP 四层模型、五层结构。

简单说,OSI是一个理论上的网络通信模型,TCP/IP是实际上的网络通信模型,五层结构就是为了介绍网络原理而折中的网络通信模型。

OSI 七层模型

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

  • 应用层:通过应用进程之间的交互来完成特定网络应用,应用层协议定义的是应用进程间通信和交互的规则,常见的协议有:HTTP FTP SMTP SNMP DNS.
  • 表示层:数据的表示、安全、压缩。确保一个系统的应用层所发送的信息可以被另一个系统的应用层读取。
  • 会话层:建立、管理、终止会话,是用户应用程序和网络之间的接口。
  • 运输层:提供源端与目的端之间提供可靠的透明数据传输,传输层协议为不同主机上运行的进程提供逻辑通信。
  • 网络层:将网络地址翻译成对应的物理地址,实现不同网络之间的路径选择, 协议有 ICMP IGMP IP 等.
  • 数据链路层:在物理层提供比特流服务的基础上,建立相邻结点之间的数据链路。
  • 物理层:建立、维护、断开物理连接。

TCP/IP 四层模型

  • 应用层:对应于 OSI 参考模型的(应用层、表示层、会话层)。
  • 传输层: 对应 OSI 的传输层,为应用层实体提供端到端的通信功能,保证了数据包的顺序传送及数据的完整性。
  • 网际层:对应于 OSI 参考模型的网络层,主要解决主机到主机的通信问题。
  • 网络接口层:与 OSI 参考模型的数据链路层、物理层对应。

TCP / IP 五层体系结构

  • 应用层:对应于 OSI 参考模型的(应用层、表示层、会话层)。
  • 传输层:对应 OSI 参考模型的的传输层
  • 网络层:对应 OSI 参考模型的的网络层
  • 数据链路层:对应 OSI 参考模型的的数据链路层
  • 物理层:对应 OSI 参考模型的的物理层。

2. 每一层对应的网络协议有哪些?

下面用一张图来总结一下常见的网络协议,大家记住下面这张图就可以了。

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

这里为了方便大家记忆,我画了一个思维导图,思维导图如下:

4. 不同层之间的数据是怎么进行传输的?

对于发送方而言,从上层到下层层层包装,对于接收方而言,从下层到上层,层层解开包装。

  • 发送方的应用进程向接收方的应用进程传送数据
  • AP先将数据交给本主机的应用层,应用层加上本层的控制信息H5就变成了下一层的数据单元
  • 传输层收到这个数据单元后,加上本层的控制信息H4,再交给网络层,成为网络层的数据单元
  • 到了数据链路层,控制信息被分成两部分,分别加到本层数据单元的首部(H2)和尾部(T2)
  • 最后的物理层,进行比特流的传输

这个过程和寄快递的包装过程有点类似,寄一个快递,每到一层,就加一个箱子,写上关于地址的信息。到了目的地之后,就一层层地拆开箱子,直到打开最后一层箱子,快递里的东西就到你的手里了。

🔖计算机网络综合


1. 你从浏览器地址栏输入 url ,到最后主页的显示,经历了哪几个过程?

这道题大概的过程比较简单,但是有很多可以细挖的点。如DNS解析、HTTP报文格式、TCP三次握手、TCP四次挥手等等,所以复习这道题的时候可以结合后面的八股文一起看。

  1. DNS 解析:将域名解析成对应的 IP 地址。
  2. TCP连接:与服务器通过三次握手,建立 TCP 连接
  3. 向服务器发送 HTTP 请求
  4. 服务器处理请求,返回 http 响应
  5. 浏览器解析并渲染页面
  6. 断开连接:TCP 四次挥手,连接结束

这里用大家最熟悉的百度的网址(www.baidu.com) 和 谷歌浏览器为例:

看完上面这个图之后,我们来探讨一下,这个过程的各个步骤使用了哪些协议呢?

www.baidu.comliu到显示主页过程使用的协议

2. DNS 的解析过程是什么样的?

DNS,英文全称是 Domain Name System,域名解析系统,它的作用也很明确,就是域名和 IP 相互映射。

DNS 的解析过程如下图所示:

DNS解析流程

如果你要查询 www.baidu.com 的 IP 地址:

  • 本地DNS服务器向根域名服务器 发送请求,根域名服务器返回负责 com 的顶级域名服务器的IP地址的列表。
  • 本地DNS服务器再向其中一个负责 com 的顶级域名服务器发送一个请求,返回负责 baidu.com 的权限域名服务器的IP地址列表。
  • 本地DNS服务器再向其中一个权限域名服务器发送一个请求,返回 www.baidu.com ****所对应的IP地址。
  • 找到本地地址后,本地 DNS 服务器会将 www.baidu.com 这个服务器的 IP 地址存储在本地的 DNS 缓存中,方便下次 DNS 服务器的寻找

3. 请你说一下常见的端口以及其对应的服务

常见端口这个应该后端程序员都不陌生,这里就不献丑了,我随便举几个例子,然后面试的时候可以根据自己熟悉的直接说就可以了:

4. 请你说一下WebSocket 与 Socket 之间的区别?

  • Socket 在计算机网络中有"套接字"的意思,其实就是等于 IP 地址 + 端口 + 协议

说具体点的,Socket 就是一套标准,它实现了对于 TCP/IP 的高度封装,可以屏蔽网络细节,以方便开发者更好地进行网络编程。

  • 而 WebSocket 就是在 Socket 的基础上实现的一个扩展,其是一个持久化的协议 ,它是伴随着 HTML 5 的出现一同产生的,用来解决 HTTP 不支持持久化连接问题的解决方案。

HTTP 为什么不支持持久化连接:

HTTP 协议自身不对请求和响应之间的通信状态进行保存。 也就是说在 HTTP 这个级别,协议对于发送过的请求或响应都 不做持久化处理 。 不保留之前一切的请求或响应报文的信息,每当有新的请求发送时,就会有对应的新响应产生, 这是为了更快地处理大量事务,确保协议的可伸缩性。

回到正题,WebSocket 和 Socket 之间有什么区别吗?

  • Socket 一个是网编编程的标准接口(即套接字) ,而 WebSocket 则是应用层的一种通信协议,其是在 Socket 的基础上实现的一种扩展。

5. 客户端的端口可以重复使用吗?

  • 在客户端执行 connect 函数的时候,只要客户端连接的服务器不是同一个内核允许端口重复使用

TCP 连接是由四元组(源IP地址,源端口,目的IP地址,目的端口) 唯一确认的,那么只要四元组中其中一个元素发生了变化,那么就表示不同的 TCP 连接的。

所以,如果客户端已使用端口 64992 与服务端 A 建立了连接,那么客户端要与服务端 B 建立连接,还是可以使用端口 64992 的,因为内核是通过四元祖信息来定位一个 TCP 连接的,并不会因为客户端的端口号相同,而导致连接冲突的问题。

6. Forward 和 Redirect的区别?

什么是 Forward 和 Redirect ?

  • 直接转发方式(Forward) ,客户端和浏览器只发出一次请求,Servlet、HTML、JSP或其它信息资源,由第二个信息资源响应该请求,在请求对象request中,保存的对象对于每个信息资源是共享的。
  • 间接转发方式(Redirect) 实际是两次HTTP请求,服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。

这里举个通俗的例子:

  • 直接转发就相当于:"A找B借钱,B说没有,B去找C借,借到借不到都会把消息传递给A";
  • 间接转发就相当于:"A找B借钱,B说没有,让A去找C借"。

看下这两个图,可以更容易理解一些:

  • Redirect 的工作原理:
  • forward 的工作原理

🕸️HTTP


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

HTTP状态码首先应该知道个大概的分类:

下面我列举一下几个常用的状态码,大家最好记一下,因为这个无论是在开发中还是在平时,都是非常重要的知识点,希望大家能记住吧:

这里找了一个之前看到的文章:程序员五一被拉去相亲,结果彻底搞懂了HTTP常用状态码,希望可以帮助大家记住常用的状态码:

我有一个朋友......

叫小星,是个北漂程序员。

小星年纪不小了,还是个单身狗。家里很着急,小星也很着急。

可是,小星起身一看,眼前一闪闪闪闪闪闪闪闪闪......

------全是秃头抠脚大汉......

前一阵子好不容易来个实习生小姑娘,分给小星带,小星高兴坏了,结果姑娘没呆三天,受不了公司的九九六跑了。

所以,部门彻底沦为了和尚部门,拔剑四顾心茫然,不见妹子只见男。

404(Not Found):服务器无法根据客户端的请求找到资源(网页)

老妈打电话又催了,小星说工作忙,没有女同事。

老妈问和你一起长大的小美还联系吗?

小美已经嫁做人妇,孩子都会叫爸爸了。

301(Moved Permanently):永久移动。请求的资源已被永久的移动到新URI。

那你大学时谈过的小静呢?

小静已经重新开始,找了新的男朋友。

302(Found):临时移动。与301类似。但资源只是临时被移动。

那我帮你安排相亲好了。

什么......好吧。

五一回家,老妈给小星安排了相亲。小星蔫头巴脑地去见相亲的小姐姐了,没想到,小姐姐还挺白净,小星一下子就支棱起来了。

小星高兴地和妹子聊了起来。妹子说她最近去过西安旅游,平时会去游泳,喜欢吃一些小吃。

------这,九九六的工作节奏基本剥夺了小星的业余生活,小星冷汗连连,只能"嗯"、"啊"。

终于,妹子问了一句,你的工作怎么样?

小星的脸上一下子泛起了红光,眼神里带着一种神圣的色彩。

你知道能应对亿级流量的高并发架构如何搭建吗?你知道高并发下保证幂等性的几种方式吗?你知道保证Redis高可用的几种方法吗......啊吧啊吧

400(Bad Request):客户端请求的语法错误,服务器无法理解。

妹子说,我吹了风,感觉头有点疼,今天就先到这吧。

500(Internal Server Error):服务器内部错误,无法完成请求。

小星垂头丧气地回家了,老妈一看小星这个样子,就知道什么情况。

--- 没有关系,明天我给你安排了第二场,好好休息准备,明天好好表现。

小星夜里失眠了,辗转反侧。

明天的姑娘是什么样?和照片上差别大吗?应该很温柔吧?......

到了半夜,小星终于睡着了。

小星做了一个好梦,他和一个叫小萌的姑娘在一起了。过了一段时间,小星想๑乛◡乛๑,小萌:๑ ͡° ͜◡ ͡° ๑,讨厌,,才确定关系多久。

403(Forbidden):服务器理解请求客户端的请求,但是拒绝执行此请求。

但是耐不住小星的软磨硬泡,还是......结果闹出人命了,但是孩子还不能生。

因为没有结婚证和准生证。

401(Unauthorized):请求需要有通过HTTP认证(BASIC认证,DIGEST认证)的认证信息。

后来,小星和小萌结婚了,生了一个可爱的孩子,一家三口过上了幸福的生活。

200(OK):请求成功。

突然,一个容嬷嬷跳了出来。

臭小子,彩礼钱没给够,挨我一针吧!

小星一下子惊醒。

还好,只是一场梦。

天已经亮了,小星强打精神,去参加今天的相亲了。

至于结果,标题里已经说明了。


故事到这里,就结束了,希望这个简单的小故事,可以帮你更加深刻地理解什么是状态码,那就来开始进入下一个问题了。

2. HTTP 状态码 301 和 302 之间有什么区别

上面已经说了,这里再说讲一遍:

  • 301(Moved Permanently):永久性移动。请求的资源已被永久的移动到新URI。 服务器返回此响应时,会返回新的资源地址。
  • 302(Found):临时性移动。与301类似。但资源只是临时被移动。 服务器从另外的地址响应资源,但是客户端还应该使用这个地址。

这里拿上面那个例子来说,301 就好比是已经嫁人了的小美,而 302 则是一个找到了新男友的小静。

3. HTTP 有哪些常用的请求方式以及用途?

HTTP 的请求方式对于开发人员来说,应该不是很陌生。其中,POST、DELETE、PUT、GET的含义分别对应我们开发中最常用的 RestFul 接口开发规范,即最熟悉的增、删、改、查,然后这里全部进行列举一下:

4. 请说一下 Get 和 Post 请求之间的区别

上面说完请求方式,然后我们在开发中最常用的便是 Get 和 Post 请求,以下从几个方面来说明GET和POST之间的区别:

  1. 传参方式 :这个从报文层面来看,Get 请求将信息放在 URL,Post 将请求信息放在请求体中 。从这一点来看,可以发现 Get 请求可以携带的数据量是有限制的,因为 URL 本身是有长度限制的,而 POST 请求的数据存放在报文体中,因此对大小没有限制。而且从形式上看,GET 请求把数据放 URL 上不太安全,而 POST 请求把数据放在请求体里想比较而言安全一些,所以,对于一般重要的信息,如密码、账户信息等,其传递的方式都是用 Post 请求多一些。
  1. 幂等性以及安全性:这个主要从数据库的方面来说,Get 请求更加符合幂等性以及安全性的要求,而 Post 请求反而没那么符合,这个主要和Http 设置的 Get/Post 请求的作用有关。按照 HTTP 的约定,GET 请求用于查看信息,不会改变服务器上的信息;而 POST 请求用来改变服务器上的信息。正因为 GET 请求只查看信息,不改变信息,对数据库的一次或多次操作获得的结果是一致的,认为它符合幂等性。安全性是指对数据库操作没有改变数据库中的数据。
  1. 能否被缓存:从浏览器缓存层面来看的,Get 请求能够直接保存在浏览器的浏览记录里面,而且 Get 请求的 URL 可以在浏览器收藏页面,这些是 Post 请求所没有的。可以这样说,Get 请求之所以被广泛的应用,就是因为其支持缓存的特性,而他之所以被选择作为缓存的方式,也是因为其幂等性以及安全性,除了返回结果以外不会对原有的数据做任务的操作,因此,绝大部分的 Get 请求都被 CDN 缓存起来了,大大减少了 Web 服务器的负担。

5. Get 请求的长度限制是多少?

在上面说过,在HTTP请求中,GET请求是通过获取 URL 中的参数来传递数据的,但是 URL 并没有对数据集的长度是没有限制的,所以真正限制 Get 长度的东西是什么呢?答案已经显而易见了,就是浏览器。

例如IE浏览器对URL的最大限制是2000多个字符,大概2kb左右,像Chrome、Firefox等浏览器支持的URL字符数更多,其中FireFox中URL的最大长度限制是65536个字符,Chrome则是8182个字符。

在这里补充一点:URL 的长度限制也不是针对数据部分,而是针对整个URL

6. 请简单说一下HTTP 请求的过程与原理

HTTP协议定义了浏览器怎么向服务器请求文档,以及服务器怎么把文档传给浏览器。

  • 每个服务器都有一个进程,它不断监听TCP的端口80,以便发现是否有浏览器向它发出连接建立请求
  • 监听到连接请求,就会建立TCP连接
  • 浏览器向服务器发出浏览某个页面的请求,服务器接着就返回所请求的页面作为响应
  • 最后,释放TCP连接

在浏览器和服务器之间的请求和相应的交互,必须按照规定的格式和遵循一定的规则,这些格式个规则就是超文本传输协议 HTTP

这道题其是和上面浏览器那道浏览器地址栏输入 url ,到最后主页的显示,经历了哪几个过程?这道题差不多,这两道题可以对比来进行记忆。

7. 说一下 HTTP 的报文结构

HTTP 的报文有两种,分别是 HTTP 请求报文 和 HTTP 响应报文

  • HTTP 请求报文

HTTP 请求报文的格式如下:

HTTP 请求报文的第一行叫做请求行,后面的行都叫做首部行,首部行后面还可以跟一个实体主体。请求首部之后有一个空行,这个空行不能省略,它是用来划分首部与实体的。

请求行包含三个字段:

  • 方法字段:包括POST、GET等请方法。
  • URL 字段
  • HTTP 报文字段
  • HTTP 响应报文

HTTP 响应报文的格式如下:

HTTP 响应报文的第一行叫做状态行 ,后面的行是首部行 ,最后是实体主体

  • 状态行包含了三个字段
    • 协议版本字段
    • 状态码
    • 相应的状态信息
  • 实体部分是报文的主要部分,它包含了所请求的对象。
  • 首部行 首部可以分为四种首部,请求首部、响应首部、通用首部和实体首部。通用首部和实体首部在请求报文和响应报文中都可以设置,区别在于请求首部和响应首部。
    • 常见的请求首部有 Accept 可接收媒体资源的类型、Accept-Charset 可接收的字符集、Host 请求的主机名。
    • 常见的响应首部有 ETag 资源的匹配信息,Location 客户端重定向的 URI。
    • 常见的通用首部有 Cache-Control 控制缓存策略、Connection 管理持久连接。
    • 常见的实体首部有 Content-Length 实体主体的大小、Expires 实体主体的过期时间、Last-Modified 资源的最后修改时间。

8. 说一下 URL 和 URI 之间的区别

  • URI,统一资源标识符(Uniform Resource Identifier, URI) ,标识的是Web上每一种可用的资源,如 HTML文档、图像、视频片段、程序等都是由一个URI进行标识的。
  • URL,统一资源定位符(Uniform Resource Location, URL) ,它是URI的一种子集,主要作用是提供资源的路径。

URL 和 URI 之间的主要区别如下:

  • URL 除了提供资源的表示外,还提供了资源的访问方式,这也是为什么我们为什么以在浏览器输入 URL 就可以找到特定网页的原因。
  • URI 相比 URL 的直接定位,其更多的是给出一个标识的东西,相当于人们常说的身份证。

这里举一个生动形象的例子:URI 是人的身份证,上面标注了人的各种信息,包括地址、生日等等,而 URL 则是一个人家里的地址,他告诉了你怎么去找到这个人,以及这个人的家庭地址在哪里,从而帮助你去找到这个人。

9. 说一下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

  • 引入了持久化连接的概念:与 HTTP/1.0 的TCP 连接方式(每次请求都需要建立一个 TCP 连接不同),其 TCP 连接默认不关闭,可以被多个请求复用。
  • 分块传输编码:即服务端每产生一块数据,就发送一块的数据,用" 流模式" 替代了" 缓存模式"。
  • 管道机制:在同一个 TCP 连接里面,客户端可以同时发送多个请求给服务端。

HTTP/2.0

  • 二进制协议: 1.1 版本的头部信息采用的是文本(ASCII 编码)的形式,数据体可以是文本或者二进制;而在 2.0 当中,其头部信息和数据体都是二进制的形式
  • 报头压缩 :HTTP 协议不带有状态,每次请求都必须附上所有信息。Http/2.0 引入了头信息压缩机制使用 gzip 或 compress 压缩后再发送
  • 完全多路复用:在 HTTP /1.0的基础上实现了扩展,即在一个连接里面了,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一进行对应。
  • 数据流优先级 :在HTTP/2中,每个请求都可以带一个31bit 的优先值,0表示最高优先级, 数值越大优先级越低。 有了这个优先值,客户端和服务器就可以在处理不同的流时采取不同的策略,以最优的方式发送流、消息和帧。
  • 服务端推送:HTTP/2 新增的另一个强大的新功能是,服务器可以对一个客户端请求发送多个响应。 换句话说,除了对最初请求的响应外,客户端允许服务器未经请求,主动地向客户端发送资源。

10. 有了解过HTTP/3吗?

HTTP/3 在前面三个协议的基础上发生了两大变化

  • 传输层基于UDP
  • 使用 QUIC保证UDP可靠性

在 说到 HTTP / 3 之前,我们先来说一下 HTTP / 2 存在的一些不足:

  1. 建立连接时间长,没办法,谁让它爸是TCP呢?我们知道,TCP三次握手的过程客户端和服务端之间需要交互三次,也就是说需要消耗1.5RTT,还有TLS加密握手,所以大概需要3RTT左右。而具体消耗的时长根据服务器和客户端之间的距离则不尽相同,如果比较近的话,消耗在100ms以内,对于用来说可能没什么感知,但是如果一个RTT的耗时达到300-400ms,那么,一次连接建立过程总耗时可能要达到一秒钟左右,这时候,用户就会明显的感知到网页加载很慢。

网络延迟又称为 RTT(Round Trip Time) 。他是指一个请求从客户端浏览器发送一个请求数据包到服务器,再从服务器得到响应数据包的这段时间。其是反映网络性能的一个重要指标。

  1. 队头阻塞问题。这里有同学会问,http2 不是解决了队头阻塞的问题吗?这里只说对了一半,http2 只解决了http消息队头阻塞问题,并没有解决TCP队头阻塞问题。

在远古的http1.1时代就存在队头阻塞问题 ,如果大家对于http的历史有一定了解的话,就会知道 http1.1 相较于http1.0最主要的改进就是引入了持久连接(keep-alive)

所谓的持久连接:在一个TCP连接上可以传送多个http请求和响应,减少了建立和关闭连接的消耗和延迟。

另外,HTTP/1.1允许在持久连接上使用请求管道,是相对于持久连接的又一性能优化。

所谓请求管道,就是在HTTP响应到达之前,可以将多条请求放入队列,当第一条HTTP请求通过网络流向服务器时,第二条和第三条请求也可以开始发送了。在高时延网络条件下,这样做可以降低网络的环回时间,提高性能。

但是,对于管道连接还是有一定的限制和要求的,其中一个比较关键的就是服务端必须按照与请求相同的顺序回送HTTP响应。

这也就意味着,如果一个响应返回发生了延迟,那么其后续的响应都会被延迟,直到队头的响应送达。这就是所谓的HTTP队头阻塞。

HTTP队头阻塞问题在HTTP2中得到了很好的解决,HTTP2废弃了管道化大的方式,而引入帧、消息和数据流的概念,客户端和服务端可以把HTTP消息分解为互不依赖的帧,然后乱序发送,最后再在另一端把它们重新组合起来。

http2 虽然很好的解决了HTTP队头阻塞的问题。但是http2仍然会存在TCP队头阻塞的问题,因为http2还是基于TCP协议实现的。

TCP传输过程中会把数据拆分成一个一个小的有序的数据包,然后经过路由器、集线器、交换机等中间设备转发,最终到达目的地。如果其中某一个数据包没有按序到达,接收端就会保持连接等待数据包返回。这时就会阻塞后续的请求,就造成了TCP队头阻塞。

HTTP/1.1 管道化持久连接也是使得同一个TCP连接可以被多个HTTP使用,但是HTTP/1.1中规定一个域名可以有6个TCP连接,而HTTP/2中,同一个域名只使用一个TCP连接,一旦HTTP/2中TCP队头阻塞所造成的影响会更大,因为HTTP/2的多路复用技术使得多个请求其实是基于同一个TCP连接的,如果某一个请求造成了TCP队头阻塞,那么多个请求都会受到影响。

说完 HTTP/2 存在的问题,接下来我们来说 HTTP/3,因为 HTTP 2 本身存在的问题是由于TCP本身的特性导致的,所以HTTP/3在QUIC的基础上进行了发展。

QUIC(Quick UDP Connections )直译为快速UDP网络连接,底层使用 UDP 进行数据传输。

HTTP/3主要有这些特点:

  • 使用UDP作为传输层进行通信
  • 在UDP的基础上QUIC协议保证了HTTP/3的安全性,在传输的过程中就完成了TLS加密握手
  • HTTPS 要建⽴⼀个连接,要花费 6 次交互,先是建⽴三次握⼿,然后是 TLS/1.3 的三次握⼿。QUIC 直接把以往的 TCP 和 TLS/1.3 的 6 次交互合并成了 3 次,减少了交互次数。
  • QUIC 有⾃⼰的⼀套机制可以保证传输的可靠性的。当某个流发⽣丢包时,只会阻塞这个流,其他流不会受到影响。

我们拿一张图看一下HTTP协议的变迁:

然后这里补充一下HTTP/1.1、HTTP/2、QUIC的数据传输过程的图片, 希望可以帮助你更加深刻地理解其区别

HTTP/1.1

HTTP/2

QUIC

11. 什么是 HTTP 的长连接,HTTP 如何设置长连接?在什么时候会超时?

什么是 HTTP 的长连接?

  1. HTTP 分为长连接和短连接,本质上说的是 TCP 的长短连接。TCP 连接是一个双向的通道,它是可以保持一段时间不关闭的,因此 TCP 连接才具有真正的长连接和短连接这一说法。
  1. 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,就会丢弃该连接。

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

这个问题记住 ****keep-alive 就好,也就是说,在HTTP中响应体的 Connection 字段指定为 ****keep-alive 就可以了

13. 说一下HTTP 与 HTTPS 有哪些区别?

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

  1. HTTP 是超⽂本传输协议,信息是明⽂传输,存在安全⻛险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在TCP 和 HTTP ⽹络层之间加⼊了 SSL/TLS 安全协议,使得报⽂能够加密传输。
  2. HTTP 连接建⽴相对简单, TCP 三次握⼿之后便可进⾏ HTTP 的报⽂传输。⽽ HTTPS 在 TCP 三次握⼿之后,还需进⾏ SSL/TLS 的握⼿过程,才可进⼊加密报⽂传输。
  3. HTTP 的端⼝号是 80,HTTPS 的端⼝号是 443。
  4. HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

14. 为什么要用HTTPS?解决了哪些问题?

因为HTTP 是明⽂传输,存在安全上的风险:

窃听⻛险,⽐如通信链路上可以获取通信内容,用户账号被盗取。

篡改⻛险,⽐如强制植⼊垃圾⼴告,造成视觉污染。

冒充⻛险,⽐如冒充淘宝⽹站,导致用户金钱损失。

所以引入了HTTPS,HTTPS 在 HTTP 与 TCP 层之间加⼊了 SSL/TLS 协议,可以很好的解决了这些风险:

  • 信息加密:交互信息⽆法被窃取。
  • 校验机制:⽆法篡改通信内容,篡改了就不能正常显示。
  • 身份证书:能证明淘宝是真淘宝。

所以SSL/TLS 协议是能保证通信是安全的。

15. HTTPS工作流程是怎样的?

这道题有几个要点:公私钥、数字证书、加密、对称加密、非对称加密

首先对于 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. 客户端收到后,用自己的密钥对其进行对称解密,得到服务器返回的数据。

如果上面的图不过瘾,这里还画了一张更详尽的图:

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

这道题感觉面试官如果要问的话,应该不仅仅会问数字签名,数字证书,很可能也会问 https 的原理,因为https原理跟数字证书有关,所以最好的话还是了解一下 Https 的原理。

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

数字证书构成: 证书包含三部分内容:证书内容、证书签名算法和签名,签名是为了验证身份。

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

浏览器验证数字证书的过程?

  1. 获取证书,得到证书内容、证书签名算法和数字签名。
  2. 用CA机构的公钥对数字签名解密(由于是浏览器信任的机构,所以浏览器会保存它的公钥)。
  3. 用证书里的签名算法对证书内容进行hash运算
  4. 比较解密后的数字签名和对证书内容做hash运算后得到的哈希值,相等则表明证书可信。

17. 客户端怎么去校验证书的合法性?

首先,服务端的证书从哪来的呢?

为了让服务端的公钥被⼤家信任,服务端的证书都是由 CA (Certificate Authority,证书认证机构)签名的,CA就是⽹络世界⾥的公安局、公证中⼼,具有极⾼的可信度,所以由它来给各个公钥签名,信任的⼀⽅签发的证书,那必然证书也是被信任的。

CA 签发证书的过程,如上图左边部分:

  • ⾸先 CA 会把持有者的公钥、⽤途、颁发者、有效时间等信息打成⼀个包,然后对这些信息进⾏ Hash 计算,得到⼀个 Hash 值;
  • 然后 CA 会使⽤⾃⼰的私钥将该 Hash 值加密,⽣成 Certificate Signature,也就是 CA 对证书做了签名;
  • 最后将 Certificate Signature 添加在⽂件证书上,形成数字证书;

客户端校验服务端的数字证书的过程,如上图右边部分:

  • ⾸先客户端会使⽤同样的 Hash 算法获取该证书的 Hash 值 H1;
  • 通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使⽤ CA 的公钥解密 Certificate
  • Signature 内容,得到⼀个 Hash 值 H2 ;
  • 最后⽐较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信。

假如在HTTPS的通信过程中,中间人篡改了证书原文,由于他没有CA机构的私钥,所以CA公钥解密的内容就不一致。

18. 如何理解 HTTP 协议是无状态的?

这个 无状态 的的 状态 值的是什么?是客户端的状态,所以字面意思,就是HTTP协议中服务端不会保存客户端的任何信息。

比如当浏览器第一次发送请求给服务器时,服务器响应了;如果同个浏览器发起第二次请求给服务器时,它还是会响应,但是呢,服务器不知道你就是刚才的那个浏览器。

那有没有什么方法可以记录这个这个状态呢?

答案是有的,就是我们接下来要说的 Cookie 和 Session。

首先,我们来看一下什么是 Cookie 和 Session:

  • Cookie 是保存在客户端的一小块文本串的数据。客户端向服务器发起请求时,服务端会向客户端发送一个 Cookie,客户端就把 Cookie 保存起来。在客户端下次向同一服务器再发起请求时,Cookie 被携带发送到服务器。服务端可以根据这个Cookie判断用户的身份和状态。
  • Session 指的就是服务器和客户端一次会话的过程。它是另一种记录客户状态的机制。不同的是cookie保存在客户端浏览器中,而session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是session。客户端浏览器再次访问时只需要从该session中查找用户的状态。
  1. 存储位置不同,Cooike 存储在客户端,Session 存储在服务器端。
  2. 存储数据类型不同,Cookie 只能保存ASCII,Session可以存任意数据类型,一般情况下我们可以在 Session 中保持一些常用变量信息,比如说 UserId 等。
  3. 有效期不同Cookie 可设置为长时间保持 比如我们经常使用的默认登录功能,Session 一般有效时间较短,客户端关闭或者 Session 超时都会失效。
  4. 隐私策略不同,Cookie 存储在客户端,比较容易遭到不法获取,早期有人将用户的登录名和密码存储在 Cookie 中导致信息被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。
  5. 存储大小不同,单个Cookie保存的数据不能超过4K,Session可存储数据远高于 Cookie。

可以使用Cookie记录Session的标识。

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

分布式环境下Session怎么处理呢?

分布式环境下,客户端请求经过负载均衡,可能会分配到不同的服务器上,假如一个用户的请求两次没有落到同一台服务器上,那么在新的服务器上就没有记录用户状态的Session。

这时候怎么办呢?

可以使用Redis等分布式缓存来存储Session,在多台服务器之间共享。

客户端无法使用Cookie怎么办?

有可能客户端无法使用Cookie,比如浏览器禁用Cookie,或者客户端是安卓、IOS等等。

这时候怎么办?SessionID怎么存?怎么传给服务端呢?

首先是SessionID的存储,可以使用客户端的本地存储,比如浏览器的sessionStorage。

接下来怎么传呢?

  • 拼接到URL里:直接把SessionID作为URL的请求参数
  • 放到请求头里:把SessionID放到请求的Header里,比较常用。

20. HTTPS TSL和TCP能同时握手吗?

HTTPS 是先进行 TCP 三次握手,再进行 TLSv1.2 四次握手

这两个协议是可以同时进行握手的,但是有一个前提:

  1. 客户端和服务端都开启了 TCP Fast Open 功能 ,而且 TSL 版本是 1.3
  2. 客户端和服务端已经完成过一次通信了;

💡TCP


1. 请你详细说一下 TCP 的三次握手机制

  • TCP 三次握手是最重要的知识点,必须要熟悉,因为这道题基本上就是送分题。

TCP提供面向连接的可靠服务,因此在数据传送之前必须要先建立连接,TCP 连接是通过三次握手建立的。

三次握手的过程:

  • 最开始,客户端和服务端都处于CLOSE状态 ,服务端监听客户端的请求,进入LISTEN状态
  • 客户端端发送连接请求,第一次握手 (SYN=1, seq=x),发送完毕后,客户端就进入 SYN_SENT 状态
  • 服务端确认连接,第二次握手 (SYN=1, ACK=1, seq=y, ACKnum=x+1), 发送完毕后,服务器端就进入 SYN_RCV 状态。
  • 客户端收到服务端的确认之后,再次向服务端确认,这就是第三次握手 (ACK=1,ACKnum=y+1),发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收到这个包时,也进入 ESTABLISHED 状态

这里举一个通俗的例子,希望可以帮助你们更好地理解 TCP 的三次握手:

在二十年前的农村,电话还没有开始普及,手机就更不用说了,所以,人与人之间的通信基本上只能靠吼来实现。

老张和老王是邻居,这天老张下地了,结果家里有事,热心的邻居老王赶紧跑到村口,开始叫唤老王。

  • 老王:老张唉!我是老王,你能听到吗?
  • 老张一听,是老王的声音:老王老王,我是老张,我能听到,你能听到吗?
  • 老王一听,嗯,没错,是老张:老张,我听到了,我有事要跟你说。
  • "你老婆要生了,赶紧回家吧!"

老张风风火火地赶回家,老婆顺利地生了个带把的大胖小子。握手的故事充满了幸福和美满。

2. TCP 为什么握手的次数是三次,为什么不能是两次或者四次?

为什么不能是两次?

  • 为了防止服务器端开启一些无用的连接增加服务器开销
  • 防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

由于网络传输是有延时的(要通过网络光纤和各种中间代理服务器),在传输的过程中,比如客户端发起了 SYN=1 的第一次握手。

如果服务器端就直接创建了这个连接并返回包含 SYN、ACK 和 Seq 等内容的数据包给客户端,这个数据包因为网络传输的原因丢失了,丢失之后客户端就一直没有接收到服务器返回的数据包。

如果没有第三次握手告诉服务器端客户端收的到服务器端传输的数据的话,服务器端是不知道客户端有没有接收到服务器端返回的信息的。

服务端就认为这个连接是可用的,端口就一直开着,等到客户端因超时重新发出请求时,服务器就会重新开启一个端口连接。这样一来,就会有很多无效的连接端口白白地开着,导致资源的浪费。

还有一种情况是已经失效的客户端发出的请求信息,由于某种原因传输到了服务器端,服务器端以为是客户端发出的有效请求,接收后产生错误。

所以我们需要"第三次握手"来确认这个过程:

通过第三次握手的数据告诉服务端,客户端有没有收到服务器"第二次握手"时传过去的数据,以及这个连接的序号是不是有效的 。若发送的这个数据是 " 收到且没有问题 " 的信息,接收后服务器就正常建立 TCP 连接,否则建立 TCP 连接失败,服务器关闭连接端口。由此减少服务器开销和接收到失效请求发生的错误。

为什么不能是四次呢?

  • 第一次握手服务端未收到SYN报文

服务端不会进行任何的动作,而客户端由于一段时间内没有收到服务端发来的确认报文,等待一段时间后会重新发送SYN报文,如果仍然没有回应,会重复这个过程,直到发送次数超过最大重传次数限制,就会返回连接建立失败。

  • 第二次握手客户端未收到服务端响应的ACK报文

客户端会继续重传,直到次数限制;而服务端此时会阻塞在accept()处,等待客户端发送ACK报文

  • 第三次握手服务端为收到客户端发送过来的ACK报文

服务端同样会采用类似客户端的超时重传机制,如果重试次数超过限制,则accept()调用返回-1,服务端建立连接失败;而此时客户端认为自己已经建立连接成功,因此开始向服务端发送数据,但是服务端的accept()系统调用已经返回,此时不在监听状态,因此服务端接收到客户端发送来的数据时会发送RST报文给客户端,消除客户端单方面建立连接的状态。

3. 三次握手中每一次没收到报文会发生什么情况?

首先我们来看一下以下这张图片,先简单了解一下 TCP 三次握手的情况。

TCP第 1 次握手丢失了,会发生什么?

  • 第一次握手服务端未收到SYN报文
  • 服务端不会进行任何的动作,而客户端由于一段时间内没有收到服务端发来的确认报文,等待一段时间后会重新发送SYN报文,如果仍然没有回应,会重复这个过程,直到发送次数超过最大重传次数限制,就会返回连接建立失败。

TCP第 2 次握手丢失了,会发生什么?

  • 第二次握手客户端未收到服务端响应的ACK报文
  • 客户端会继续重传,直到次数限制;而服务端此时会阻塞在accept()处,等待客户端发送ACK报文

TCP第 3 次握手丢失了,会发生什么?

  • 第三次握手服务端为收到客户端发送过来的ACK报文
  • 服务端同样会采用类似客户端的超时重传机制,如果重试次数超过限制,则accept()调用返回-1,服务端建立连接失败;而此时客户端认为自己已经建立连接成功,因此开始向服务端发送数据,但是服务端的accept()系统调用已经返回,此时不在监听状态,因此服务端接收到客户端发送来的数据时会发送RST报文给客户端,消除客户端单方面建立连接的状态。

4. 第 2 次握手传回了 ACK,为什么还要传回 SYN 呢?

ACK是为了告诉客户端传来的数据已经接收无误

而传回 SYN 是为了告诉客户端服务端响应的确实是客户端发送的报文

5. 第 3 次握手可以携带数据吗?

第3次握手是可以携带数据的。

此时客户端已经处于ESTABLISHED状态。对于客户端来说,它已经建立连接成功,并且确认服务端的接收和发送能力是正常的。

第一次握手不能携带数据是出于安全的考虑,因为如果允许携带数据,攻击者每次在SYN报文中携带大量数据,就会导致服务端消耗更多的时间和空间去处理这些报文,会造成CPU和内存的消耗。

6. 什么是半连接队列?什么是全连接队列?

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

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

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

综上所述,可以得到以下结论:半连接队列 存放的是三次握手未完成的连接全连接队列 存放的是完成三次握手的连接

7. 什么是 SYN Flood?然后 SYN Flood 攻击和半连接队列有什么关系呢?

什么是 SYN Flood?

SYN Flood 是一种典型的 DDos 攻击 ,它在短时间内,伪造 不存在的 IP 地址 , 向服务器发送大量SYN 报文。当服务器回复 SYN+ACK 报文后,不会收到 ACK 回应报文,那么SYN队列里的连接旧不会出对队,久⽽久之就会占满服务端的 SYN 接收队列(半连接队列),使得服务器不能为正常⽤户服务。

那有什么应对方案呢?

主要有 SYN CookieSYN Proxy 防火墙 等。

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

8. 说一下 TCP 四次挥手的过程?

说完三次握手,也该说说四次挥手了,别问为什么,问就是这个也是重点。

接下来我们先来看一个图:

TCP 四次挥手过程:

  • 数据传输结束之后,通信双方都可以主动发起断开连接请求,这里假定客户端发起
  • 客户端发送释放连接报文,第一次挥手 (FIN=1,seq=u),发送完毕后,客户端进入 FIN_WAIT_1 状态。
  • 服务端发送确认报文,第二次挥手 (ACK=1,ack=u+1,seq =v),发送完毕后,服务器端进入 CLOSE_WAIT 状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2 状态。
  • 服务端发送释放连接报文,第三次挥手 (FIN=1,ACK1,seq=w,ack=u+1),发送完毕后,服务器端进入 L AST_ACK 状态,等待来自客户端的最后一个 ACK。
  • 客户端发送确认报文,第四次挥手 (ACK=1,seq=u+1,ack=w+1),客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT 状态,等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后 ,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是客户端自己也关闭连接,进入 CLOSED 状态 。服务器端接收到这个确认包之后,关闭连接,进入 CLOSED 状态

这里,我们同样举一个例子来帮助大家理解:

假如某单身狗 up 主有一个女朋友,但是呢,由于博主上班九九六,下班又肝视频,导致他没有时间去陪女朋友,于是,有一天他的女朋友忍无可忍,终于选择提出了分手。

  • 女朋友:狗男人,最近你都不理我,你是不是不爱我了?你是不是外面有别的狗子了?我要和你分手?
  • 沙雕 up 主听完一愣,怒火攻心:分手就分手,不陪你闹了,等我把东西收拾一下。

于是,沙雕 up主小心翼翼地装起了自己的青轴机械键盘。

  • 沙雕 up 主:哼,蠢女人,我已经收拾完了,我先滚为敬,再见!
  • 女朋友:滚,滚的远远的,越远越好,我一辈子都不想再见到你。

就这样,沙雕 up 主和他的女友选择了分手。

哎,从这里可以看出,挥手的故事总是充满了悲伤和遗憾的😩😩😩!

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

再来回顾下四次挥手双方发 FIN 包的过程,就能理解 TCP 为什么需要四次了。

  • 关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
  • 服务端收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。

从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACKFIN 一般都会分开发送,所以,挥手的过程就比握手的过程多了一次。

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

为什么需要等待?

1. 为了保证客户端发送的最后一个 ACK 报文段能够到达服务端 这个 ACK 报文段有可能丢失,因而使处在 LAST-ACK 状态的服务端就收不到对已发送的 FIN + ACK 报文段的确认。服务端会超时重传这个 FIN+ACK 报文段,而客户端就能在 2MSL 时间内(超时 + 1MSL 传输 )收到这个重传的 FIN+ACK 报文段。接着客户端重传一次确认,重新启动 2MSL 计时器。最后,客户端和服务器都正常进入到 CLOSED 状态。

2. 防止已失效的连接请求报文段出现在本连接中。客户端在发送完最后一个 ACK 报文段后,再经过时间 2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个连接中不会出现这种旧的连接请求报文段。

为什么等待的时间是2MSL?

MSL 是 Maximum Segment Lifetime,报⽂最⼤⽣存时间,它是任何报⽂在⽹络上存在的最⻓时间,超过这个时间报⽂将被丢弃。

TIME_WAIT 等待 2 倍的 MSL ,⽐较合理的解释是:⽹络中可能存在来⾃发送⽅的数据包,当这些发送⽅的数据包被接收⽅处理后⼜会向对⽅发送响应,所以⼀来⼀回需要等待 2 倍的时间。

⽐如如果被动关闭⽅没有收到断开连接的最后的 ACK 报⽂,就会触发超时重发 Fin 报⽂,另⼀⽅接收到 FIN 后,会重发 ACK 给被动关闭⽅, ⼀来⼀去正好 2 个 MSL。

11. 保活计时器有什么作用呢?

除时间等待计时器外,TCP 还有一个保活计时器(keepalive timer)

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

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

12. CLOSE-WAIT 和 TIME-WAIT 的状态和意义?

CLOSE-WAIT状态有什么意义?

服务端收到客户端关闭连接的请求并确认之后,就会进入CLOSE-WAIT状态。此时服务端可能还有一些数据没有传输完成,因此不能立即关闭连接,而CLOSE-WAIT状态就是为了保证服务端在关闭连接之前将待发送的数据处理完。

TIME-WAIT有什么意义?

TIME-WAIT状态发生在第四次挥手,当客户端向服务端发送ACK确认报文后进入TIME-WAIT状态。

它存在的意义主要是两个:

  1. 保证连接正确关闭

假设客户端最后一次发送的ACK包在传输的时候丢失了,由于TCP协议的超时重传机制,服务端将重发FIN报文,如果客户端没有维持TIME-WAIT状态而直接关闭的话,当收到服务端重新发送的FIN包时,客户端就会使用RST包来响应服务端,导致服务端以为有错误发生,然而实际关闭连接过程是正常的。

  1. 防止旧连接数据包

如果客户端收到服务端的FIN报文之后立即关闭连接,但是此时服务端对应的端口并没有关闭,如果客户端在相同端口建立新的连接,可能会导致新连接收到旧连接残留的数据包,导致不可预料的异常发生。

13. TIME_WAIT 状态过多会导致什么问题?怎么解决?

TIME_WAIT 状态过多会导致什么问题?

如果服务器有处于 TIME-WAIT 状态的 TCP,则说明是由服务器⽅主动发起的断开请求。

过多的 TIME-WAIT 状态主要的危害有两种:

  1. 内存资源占⽤;
  2. 对端⼝资源的占⽤,⼀个 TCP 连接⾄少消耗⼀个本地端⼝;

怎么解决TIME_WAIT 状态过多?

  • 服务器可以设置SO_REUSEADDR套接字来通知内核,如果端口被占用,但是TCP连接位于TIME_WAIT 状态时可以重用端口。
  • 还可以使用长连接的方式来减少TCP的连接和断开,在长连接的业务里往往不需要考虑TIME_WAIT状态。

14. 说说 TCP 报文首部的格式,以及有什么作用呢?

看一下TCP报文首部的格式:

报文格式以及作用如下:

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

15. TCP 是如何保证连接的可靠性的?

  1. 连接管理:TCP使用三次握手和四次挥手保证可靠地建立连接和释放连接,这里就不用多说了。
  2. 校验和:TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果接收端的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
  1. 序列号/确认应答:TCP 给发送的每一个包进行编号,接收方会对收到的包进行应答,发送方就会知道接收方是否收到对应的包,如果发现没有收到,就会重发,这样就能保证数据的完整性。就像老师上课,会问一句,这一章听懂了吗?没听懂再讲一遍。
  1. 流量控制:TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。(TCP 利用滑动窗口实现流量控制)
  1. 最大消息长度:在建立TCP连接的时候,双方约定一个最大的长度(MSS)作为发送的单位,重传的时候也是以这个单位来进行重传。理想的情况下是该长度的数据刚好不被网络层分块。
  1. 超时重传:超时重传是指发送出去的数据包到接收到确认包之间的时间,如果超过了这个时间会被认为是丢包了,需要重传。
  1. 拥塞控制:如果网络非常拥堵,此时再发送数据就会加重网络负担,那么发送的数据段很可能超过了最大生存时间也没有到达接收方,就会产生丢包问题。为此TCP引入慢启动机制,先发出少量数据,就像探路一样,先摸清当前的网络拥堵状态后,再决定按照多大的速度传送数据。

16. 讲述一下 TCP 的流量控制?

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

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

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

17. 聊一聊 TCP 的滑动窗口?

TCP 发送一个数据,如果需要收到确认应答,才会发送下一个数据。这样的话就会有个缺点:效率会比较低。

这里举一个例子:"我们在微信上聊天,你打完一句话,我回复一句之后,你才能打下一句。假如我没有及时回复呢?你是把话憋着不说吗?然后傻傻等到我回复之后再接着发下一句?"

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

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

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

TCP 滑动窗口分为两种: 发送窗口和接收窗口。

TCP 发送窗口

发送端的滑动窗口 ****包含四大部分,如下:

  • 已发送且已收到 ACK 确认
  • 已发送但未收到 ACK 确认
  • 未发送但可以发送
  • 未发送也不可以发送
  • 深蓝色框里就是发送窗口
  • SND.WND: 表示发送窗口的大小, 上图虚线框的格子数是 10个,即发送窗口大小是 10。
  • SND.NXT:下一个发送的位置,它指向未发送但可以发送的第一个字节的序列号。
  • SND.UNA: 一个绝对指针,它指向的是已发送但未确认的第一个字节的序列号。

TCP 滑动窗口

  • 已成功接收并确认
  • 未收到数据但可以接收
  • 未收到数据并不可以接收的数据
  • 蓝色框内,就是接收窗口
  • REV.WND: 表示接收窗口的大小, 上图虚线框的格子就是 9 个。
  • REV.NXT: 下一个接收的位置,它指向未收到但可以接收的第一个字节的序列号。

18. 了解过 Nagle 算法以及延迟确认吗?

Nagle 算法和延迟确认是干什么的?

当我们 TCP 报⽂的承载的数据⾮常⼩的时候,例如⼏个字节,那么整个⽹络的效率是很低的,因为每个 TCP 报⽂中都会有 20 个字节的 TCP 头部,也会有 20 个字节的 IP 头部,⽽数据只有⼏个字节,所以在整个报⽂中有效数据占有的比例就会⾮常低。

这就好像快递员开着⼤货⻋送⼀个⼩包裹⼀样浪费。

那么就出现了常⻅的两种策略,来减少⼩报⽂的传输,分别是:

  • Nagle 算法
  • 延迟确认

Nagle 算法

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

Nagle 算法的策略:

  • 没有已发送未确认报⽂时,⽴刻发送数据。
  • 存在未确认报⽂时,直到「没有已发送未确认报⽂」或「数据⻓度达到 MSS ⼤⼩」时,再发送数据。

只要没满⾜上⾯条件中的⼀条,发送⽅⼀直在囤积数据,直到满⾜上⾯的发送条件。

延迟确认

事实上当没有携带数据的 ACK,它的⽹络效率也是很低的,因为它也有 40 个字节的 IP 头 和 TCP 头,但却没有携带数据报⽂。

为了解决 ACK 传输效率低问题,所以就衍⽣出了 TCP 延迟确认。

TCP 延迟确认的策略:

  • 当有响应数据要发送时,ACK 会随着响应数据⼀起⽴刻发送给对⽅
  • 当没有响应数据要发送时,ACK 将会延迟⼀段时间,以等待是否有响应数据可以⼀起发送
  • 如果在延迟等待发送 ACK 期间,对⽅的第⼆个数据报⽂⼜到达了,这时就会⽴刻发送 ACK

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

19. 什么是拥塞控制,不是已经有了流量控制了吗?

前⾯的流量控制是避免发送⽅的数据填满接收⽅的缓存,但是并不知道整个⽹络之中发⽣了什么。

⼀般来说,计算机⽹络都处在⼀个共享的环境。因此也有可能会因为其他主机之间的通信使得⽹络拥堵。

在⽹络出现拥堵时,如果继续发送⼤量数据包,可能会导致数据包时延、丢失等,这时 TCP 就会重传数据,但是⼀重传就会导致⽹络的负担更重,于是会导致更⼤的延迟以及更多的丢包,这个情况就会进⼊恶性循环被不断地放⼤....

所以,TCP 不能忽略整个网络中发⽣的事,它被设计成⼀个⽆私的协议,当⽹络发送拥塞时,TCP 会⾃我牺牲,降低发送的数据流。

于是,就有了拥塞控制,控制的⽬的就是避免发送⽅的数据填满整个⽹络。

就像是一个水管,不能让太多的水(数据流)流入水管,如果超过水管的承受能力,水管会被撑爆(丢包)。

发送方维护一个拥塞窗口 cwnd(congestion window) 的变量,调节所要发送数据的量。

20. 什么是拥塞窗口?和发送窗口有什么关系呢?

拥塞窗⼝ cwnd 是发送⽅维护的⼀个的状态变量,它会根据⽹络的拥塞程度动态变化的。

发送窗⼝ swnd 和接收窗⼝ rwnd 是约等于的关系,那么由于加⼊了拥塞窗⼝的概念后,此时发送窗⼝的值是 swnd = min(cwnd, rwnd) ,也就是拥塞窗⼝和接收窗⼝中的最⼩值。

拥塞窗⼝ cwnd 变化的规则:

  • 只要⽹络中没有出现拥塞, cwnd 就会增⼤;
  • 但⽹络中出现了拥塞, cwnd 就减少;

21. 拥塞控制有哪些常用的算法了?

拥塞控制主要有这几种常用算法,如下图所示:

慢启动算法

慢启动算法,慢慢启动。

它表示 TCP 建立连接完成后,一开始不要发送大量的数据,而是先探测一下网络的拥塞程度。由小到大逐渐增加拥塞窗口的大小,如果没有出现丢包,每收到一个 ACK,就将拥塞窗口 cwnd 大小就加 1(单位是 MSS)每轮次发送窗口增加一倍,呈指数增长,如果出现丢包,拥塞窗口就减半,进入拥塞避免阶段。

举个例子:

  • 连接建⽴完成后,⼀开始初始化 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 到达该阀值后,就好像水管被关小了水龙头一样,减少拥塞状态。即当 cwnd>ssthresh 时,进入了拥塞避免算法。

拥塞避免算法

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

  • 每收到一个 ACK 时,cwnd = cwnd + 1/cwnd
  • 当每过一个 RTT 时,cwnd = cwnd + 1

显然这是一个线性上升的算法,避免过快导致网络拥塞问题。

接着上面慢启动的例子,假定 ssthresh 为 8 ::

  • 当 8 个 ACK 应答确认到来时,每个确认增加 1/8,8 个 ACK 确认 cwnd ⼀共增加 1,于是这⼀次能够发送 9个 MSS ⼤⼩的数据,变成了线性增⻓。

拥塞发生算法

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

  • RTO 超时重传
  • 快速重传

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

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

发⽣快速重传的拥塞发⽣算法:

  • 拥塞窗口大小 cwnd = cwnd/2
  • 慢启动阀值 ssthresh = cwnd
  • 进入快速恢复算法

快速恢复算法

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

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

  • cwnd = cwnd /2

  • sshthresh = cwnd

然后,进⼊快速恢复算法如下:

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

22. 可以简单说一下TCP 的重传机制吗?

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

超时重传

超时重传,是 TCP 协议保证数据可靠性的另一个重要机制,其原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的 ACK 报文,那么就重新发送数据,直到发送成功为止。

超时时间应该设置为多少呢?

先来看下什么叫 RTT(Round-Trip Time,往返时间)

RTT 就是数据完全发送完,到收到确认信号的时间,即数据包的一次往返时间。

超时重传时间,就是 RTO(Retransmission Timeout)。那么,RTO 到底设置多大呢?

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

一般来说,RTO 略微大于 RTT,效果是最佳的。

其实,RTO 有个标准方法的计算公式,也叫 Jacobson / Karels 算法

  1. 首先计算 SRTT(即计算平滑的 RTT)
  1. 其次,计算 RTTVAR (round-trip time variation)
  1. 最后,得出最终的 RTO

在 Linux 下,α = 0.125β = 0.25μ = 1∂ = 4。别问这些参数是怎么来的,它们是大量实践,调出的最优参数。

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

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

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

快速重传

TCP 还有另外⼀种快速重传(Fast Retransmit) 机制,它不以时间为驱动,⽽是以数据驱动重传。

它不以时间驱动,而是以数据驱动。它是基于接收端的反馈信息来引发重传的。

可以用它来解决超时重发的时间等待问题,快速重传流程如下:

在上图,发送⽅发出了 1,2,3,4,5 份数据:

  • 第⼀份 Seq1 先送到了,于是就 Ack 回 2;
  • 结果 Seq2 因为某些原因没收到,Seq3 到达了,于是还是 Ack 回 2;
  • 后⾯的 Seq4 和 Seq5 都到了,但还是 Ack 回 2,因为 Seq2 还是没有收到;
  • 发送端收到了三个 Ack = 2 的确认,知道了 Seq2 还没有收到,就会在定时器过期之前,重传丢失的 Seq2
  • 最后,收到了 Seq2,此时因为 Seq3,Seq4,Seq5 都收到了,于是 Ack 回 6 。

快速重传机制只解决了⼀个问题,就是超时时间的问题,但是它依然⾯临着另外⼀个问题。就是重传的时候,是重传之前的⼀个,还是重传所有的问题。

⽐如对于上⾯的例⼦,是重传 Seq2 呢?还是重传 Seq2、Seq3、Seq4、Seq5 呢?因为发送端并不清楚这连续的三个 Ack 2 是谁传回来的。

根据 TCP 不同的实现,以上两种情况都是有可能的。可⻅,这是⼀把双刃剑。

为了解决不知道该重传哪些 TCP 报⽂,于是就有 SACK ⽅法。

带选择确认的重传(SACK)

为了解决应该重传多少个包的问题? TCP 提供了

带选择确认的重传(即 SACK,Selective Acknowledgment)

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

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

重复 SACK(D-SACK)

D-SACK,英文是 Duplicate SACK ,是在 SACK 的基础上做了一些扩展 ,主要用来告诉发送方,有哪些数据包,自己重复接受了

DSACK 的目的是帮助发送方判断,是否发生了包失序、ACK 丢失、包重复或伪重传,从而让 TCP 可以更好的做网络流控。

例如ACK丢包导致的数据包重复:

  • 接收⽅发给发送⽅的两个 ACK 的确认应答都丢失了,所以发送⽅超时后,重传了第⼀个数据包(3000 ~3499)
  • 于是接收⽅发现数据是重复收到的,于是回了⼀个 SACK = 3000~3500,告诉「发送⽅」 3000~3500的数据早已被接收了,因为 ACK 都到了 4000 了,已经意味着 4000 之前的所有数据都已收到,所以这个SACK 就代表着 D-SACK 。这样发送⽅就知道了,数据没有丢,是接收⽅的 ACK 确认报⽂丢了。

23. 说一下 TCP 的粘包和拆包?

什么是TCP粘包和拆包?

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

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

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

怎么解决粘包和拆包

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

24. 一台机器最多可以支撑多少个 TCP 连接?

一台机器最大究竟能支持多少个网络连接?这个简单的问题里其实埋了坑,导致无数的英雄好汉被困惑不解。就和树上九只鸟打死一只还剩几只的问题一样,没有和你说清楚树上是真鸟,还是假鸟,也没有说枪是有声还是无声的。所有,我们今天来做一个总结:

  • TCP连接的服务端机 对于有1个 IP 的客户端来说,受限于 IP_LOCAL_PORT_RANGE 参数,也受限于65535。但单Linux可以配置多个 IP ,有几个 IP,最大理论值就翻几倍。

多张网卡不是必须的。即使只有一张网卡,也可以配置多 IP。K8S 就是这么干的,在K8S里面,一台物理机上可以部署多个Pod。但每一个 Pod 都会被分配一个独立的 IP,所以完全不用担心物理机上部署了过多的 Pod 而影响你用的 Pod 里的TCP连接数量。在 IP 给你的那一刻,你的 Pod 就和其它应用隔离开了。

  • TCP连接的服务器机 每一个监听的端口虽然理论值很大,但这个数字没有实际意义。最大并发数取决你的内存大小。一条TCP连接如果不发送数据的话,消耗内存是3.3K左右,假设你只保持连接不发送数据,那么你服务器可以建立的连接最大数量 = 你的内存/3.3K。 假如是4GB的内存,那么大约可接受的TCP连接数量是100万左右。

这个例子里,我们考虑的前提是在一个进程下 Hold 所有的服务器端连接。而在实际中的项目里,为了收发数据方便,很多网络IO模型还会为TCP连接再创建一个线程或协程。拿最轻量的 Golang 来说,一个协程栈也需要2KB的内存开销。

25. 拔掉网线之后,原有的 TCP 连接还在吗?

TCP 连接在 Linux 内核中是一个名为 Struct Socket 的结构体 ,该结构体的内容包含 TCP 连接的状态等信息。当拔掉网线的时候,操作系统并不会变更该结构体的任何内容,所以 TCP 连接的状态也不会发生改变。

26. 如何在 Linux 上查看 TCP 状态呢?

TCP 的连接状态查看,在 Linux 可以通过 netstat -napt 命令查看

✨UDP

网上看了很多的面经,感觉 UDP 问的不多,基本上都是拿来和 TCP 作比较了。


1. 什么是 UDP 的单播、广播、多播?

  1. UDP 单播:单播用于两个主机之间的端对端通信。
  2. 广播 UDP 与单播 UDP 的主要区别就是 IP 地址不同,广播使用广播地址 255.255.255.255 ,通过该 IP 地址可将消息发送到在同一广播网络上的每个主机。值得强调的是:本地广播信息是不会被路由器转发。当然这是十分容易理解的,因为如果路由器转发了广播信息,那么势必会引起网络瘫痪。这也是为什么IP协议的设计者故意没有定义互联网范围的广播机制。广播地址通常用于在网络游戏中处于同一本地网络的玩家之间交流状态信息等。其实广播顾名思义,就是想局域网内所有的人说话,但是广播还是要指明接收者的端口号的,因为不可能接受者的所有端口都来收听广播。
  3. 多播,也称为"组播",将网络中同一业务类型主机进行了逻辑上的分组,进行数据收发的时候其数据仅仅在同一分组中进行,其他的主机没有加入此分组不能收发对应的数据。

多播的应用主要有网上视频、网上会议等。

2. 说说 TCP 和 UDP 之间的区别?

最根本区别:TCP 是面向连接,而 UDP 是无连接

你可以类比一下:TCP是打电话,UDP是村口的广播。

3. TCP 和 UDP 的应用场景有哪些?

这个问题你可以结合上面结合 TCP 和 UDP 之间的区别一起记忆。

  • TCP应用场景: 效率要求相对低,但对准确性要求相对高的场景。因为传输中需要对数据确认、重发、排序等操作,相比之下效率没有UDP高。例如:文件传输(准确高要求高、但是速度可以相对慢)、收发邮件、远程登录。
  • UDP应用场景: 效率要求相对高,对准确性要求相对低的场景。例如:QQ聊天、在线视频、网络语音电话(即时通讯,速度要求高,但是出现偶尔断续不是太大问题,并且此处完全不可以使用重发机制)、广播通信(广播、多播)。

4. 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的应用层协议:NFS、DHCP、DNS、TFTP、SNMP

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

5. 简单说说 UDP 的协议格式?

UDP 协议格式

UDP报文格式参数解析

  1. 16位源端口号:表示数据从哪里来
  2. 16位目的端口号:表示数据要到哪里去
  3. 16位UDP长度:表示整个数据报(UDP首部+UDP数据)的长度
  4. 16位UDP检验和:如果UDP报文的检验和出错,就会直接将报文丢弃

注:端口号大部分都是16位的,其根本原因就是因为传输层协议当中的端口号就是16位的

  • UDP如何将报头与有效载荷进行分离:

UDP报头是一种定长报头,UDP在读取报文时读取完前8个字节(报头)后剩下的就都是有效载荷了

  • UDP如何将有效载荷交付给上层协议:

获取到一个报文后从该报文的前8个字节中提取出对应的目的端口号,通过目的端口号找到对应的上层应用层进程进行交付

  • UDP 使用注意事项:
  1. UDP协议首部中有一个16位的最大长度,也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部)
  2. 如果我们需要传输的数据超过64K, 就需要在应用层手动的分包,多次发送,并在接收端手动拼装

6. UDP 协议存在的意义

  1. TCP协议是可靠的协议,也就意味着TCP协议需要做更多的工作来保证传输数据的可靠,此时需要的成本相比于UDP更高
  2. UDP协议是不可靠的协议,也就意味着UDP协议不需要考虑数据传输时可能出现的问题,但UDP无论是使用还是维护都足够简单
  3. 虽然TCP复杂,但TCP的效率不一定比UDP低,TCP当中不仅有保证可靠性的机制,还有保证传输效率的其他机制
  4. 网络通信时具体采用TCP还是UDP完全取决于上层的应用场景。如果应用场景严格要求数据在传输过程中的可靠性,那么就必须采用TCP协议,如果应用场景允许数据传输出现少量丢包,那么肯定优先选择UDP协议,因为UDP协议足够简单

7. 为什么 QQ 采用 UDP 协议作为传输协议?

这个是之前在知乎上看到的一个话题,在整理的时候刚好又遇到了,所以来讲一讲。

  • 首先,QQ并不是完全基于UDP实现。比如在使用QQ进行文件传输等活动的时候,就会使用TCP作为可靠传输的保证。
  • 使用UDP进行交互通信的好处在于,延迟较短,对数据丢失的处理比较简单。同时,TCP是一个全双工协议,需要建立连接,所以网络开销也会相对大。
  • 如果使用QQ语音和QQ视频的话,UDP的优势就更为突出了,首先延迟较小。最重要的一点是不可靠传输,这意味着如果数据丢失的话,不会有重传。因为用户一般来说可以接受图像稍微模糊一点,声音稍微不清晰一点,但是如果在几秒钟以后再出现之前丢失的画面和声音,这恐怕是很难接受的。
  • 由于QQ的服务器设计容量是海量级的应用,一台服务器要同时容纳十几万的并发连接,因此服务器端只有采用UDP协议与客户端进行通讯才能保证这种超大规模的服务

简单总结一下:UDP协议是无连接方式的协议,它的效率高,速度快,占资源少,对服务器的压力比较小。但是其传输机制为不可靠传送,必须依靠辅助的算法来完成传输控制。QQ采用的通信协议以UDP为主,辅以TCP协议。

8. UDP 协议为什么不可靠?

UDP 在传输数据之前不需要先建立连接,服务器的传输层在接收到 UDP 报文之后,由于其没有确认机制,所以不需要进行确认,也不需要提供可靠交付,综上所述,可以大致总结为以下几个方面:

  1. 不保证消息交付:不确认,不重传,无超时
  2. 不保证交付顺序:不设置包序号,不重排,不会发生队首阻塞
  3. 不进行拥塞控制:不内置客户端或网络反馈机制
  4. 不跟踪连接转态:不内置客户端或网络反馈机制

9. DNS 为什么要使用 UDP协议?

准确来说,TCP 和 QQ 一样,也是即使用 TCP,又使用 UCP 的。

  • 当客户端想DNS服务器查询域名(域名解析)的时候,一般返回的内容不会超过UDP报文的最大长度,即512字节,用UDP传输时,不需要创建连接,从而大大提高了响应速度,但这要求域名解析服务器和域名服务器都必须自己处理超时和重传从而保证可靠性。
  • 当进行区域传送(主域名服务器向辅助域名服务器传送变化的那部分数据)时会使用TCP,因为数据同步传送的数据量比一个请求和应答的数据量要多,而TCP允许的报文长度更长,因此为了保证数据的正确性,会使用基于可靠连接的TCP。

10. TCP 和 UDP 可以同时绑定相同的端口吗?

可以的,传输层的「端口号」的作用,是为了区分同一个主机上不同应用程序的数据包,传输层有两个传输协议分别是 TCP 和 UDP,在内核中是两个完全独立的软件模块。

当主机收到数据包后,可以在 IP 包头的「协议号」字段知道该数据包是 TCP/UDP,所以可以根据这个信息确定送给哪个模块(TCP/UDP)处理,送给 TCP/UDP 模块的报文根据「端口号」确定送给哪个应用程序处理。

🌕IP


1. VIP 协议以及地址漂移?

VIP 即虚拟 IP 地址是一个不与特定计算机或一个计算机中的网络接口卡(NIC)相连的 IP 地址。数据包被发送到这个 VIP 地址,但是所有的数据还是经过真实的网络接口。

何为虚拟IP,就是一个未分配给真实主机的IP,也就是说对外提供数据库服务器的主机除了有一个真实IP外还有一个虚拟IP,使用这两个IP中的 任意一个都可以连接到这台主机,所有项目中数据库链接一项配置的都是这个虚IP,当服务器发生故障无法对外提供服务时,动态将这个虚IP切换到备用主机。

至于如何切换,其实现原理主要是靠 TCP/IP 的 ARP 协议。因为 IP 地址只是一个逻辑地址,在以太网中 MAC 地址才是真正用来进行数据传输的物理地址,每台主机中都有一个 ARP 高速缓存,存储同一个网络内的 IP 地址与 MAC 地址的对应关系,以太网中的主机发送数据时会先从这个缓存中查询目标 IP 对应的 MAC 地址,会向这个 MAC 地址发送数据。操作系统会自动维护这个缓存,这就是整个实现的关键。

2. 端到端、点到点之间的区别是什么?

数据传输的可靠性是通过数据链路层和网络层的点对点和传输层的端对端保证的。端到端与点到点是针对网络中传输的两端设备间的关系而言的。

  • 端到端通信是针对传输层来说的。它是一个网络连接,指的是在数据传输之前,在发送端与接收端之间(忽略中间有多少设备)为数据的传输建立一条链路,链路建立以后,发送端就可以发送数据,知道数据发送完毕,接收端确认接收成功。 也就是说在数据传输之前,先为数据的传输开辟一条通道,然后在进行传输。从发送端发出数据到接收端接收完毕结束。
  • 点到点通信是针对数据链路层或网络层来说的。点对点是基于 MAC 地址或 IP 地址。指一个设备发数据给与该该设备直接连接的其他设备,这台设备又在合适的时候将数据传递给与它相连的下一个设备,通过一台一台直接相连的设备把数据传递到接收端。

其主要区别还是,端到端关心的开始与结束,点到点关心的中间过程。可以说 端到端是由无数个点到点构成的。

3. IP 协议是什么?IP 协议有什么作用吗?

IP协议是什么?

IP协议(Internet Protocol)又被称为互联网协议,是支持网间互联的数据包协议,工作在网际层,主要目的就是为了提高网络的可扩展性。

通过网际协议IP ,可以把参与互联的,性能各异的网络看作一个统一的网络

和传输层TCP相比,IP协议是一种无连接/不可靠、尽力而为的数据包传输服务,和TCP协议一起构成了TCP/IP协议的核心。

IP协议有哪些作用?

IP协议主要有以下几个作用:

  • 寻址和路由:在IP数据报中携带源IP地址和目的IP地址来表示该数据包的源主机和目标主机。IP数据报在传输过程中,每个中间节点(IP网关、路由器)只根据网络地址来进行转发,如果中间节点是路由器,则路由器会根据路由表选择合适的路径。IP协议根据路由选择协议提供的路由信息对IP数据报进行转发,直至目标主机。
  • 分段和重组:IP数据报在传输过程中可能会经过不同的网络,在不同的网络中数据报的最大长度限制是不同的,IP协议通过给每个IP数据报分配一个标识符以及分段与组装的相关信息,使得数据报在不同的网络中能够被传输,被分段后的IP数据报可以独立地在网络中进行转发,在达到目标主机后由目标主机完成重组工作,恢复出原来的IP数据报。

传输层协议和网络层协议有什么区别?

网络层协议负责提供主机间的逻辑通信;传输层协议负责提供进程间的逻辑通信。

4. IP 地址有哪些分类?

一个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):以 1111开头,保留位为将来使用

5. 域名 和 IP 有什么关系?一个 IP 可以对应多个域名吗?

  • IP地址在同一个网络中是惟一的,用来标识每一个网络上的设备,其相当于一个人的身份证号
  • 域名在同一个网络中也是惟一的,就像是一个人的名字、绰号

假如你有多个不用的绰号,你的朋友可以用其中任何一个绰号叫你,但你的身份证号码却是惟一的。但同时你的绰号也可能和别人重复,假如你不在,有人叫你的绰号,其它人可能就答应了。

一个域名可以对应多个IP,但这种情况DNS做负载均衡的,在用户访问过程中,一个域名只能对应一个IP。而一个IP却可以对应多个域名,是一对多的关系。

6. IPV4 地址不够,这个问题怎么解决?

我们知道,IP地址有32位,可以标记2的32次方个地址,听起来很多,但是全球的网络设备数量已经远远超过这个数字,所以IPV4地址已经不够用了,那怎么解决呢?

  • DHCP:动态主机配置协议,动态分配IP地址,只给接入网络的设备分配IP地址,因此同一个MAC地址的设备,每次接入互联网时,得到的IP地址不一定是相同的,该协议使得空闲的IP地址可以得到充分利用。
  • CIDR:无类别域间路由。CIDR消除了传统的A类、B类、C类地址以及划分子网的概念,因而更加有效地分配IPv4的地址空间,但无法从根本上解决地址耗尽的问题。
  • NAT:网络地址转换协议,我们知道属于不同局域网的主机可以使用相同的IP地址,从而一定程度上缓解了IP资源枯竭的问题,然而主机在局域网中使用的IP地址是不能在公网中使用的,当局域网主机想要与公网主机进行通信时,NAT方法可以将该主机IP地址转换为全球IP地址。该协议能够有效解决IP地址不足的问题。
  • IPv6:作为接替IPv4的下一代互联网协议,其可以实现2的128次方个地址,而这个数量级,即使给地球上每一粒沙子都分配一个IP地址也够用,该协议能够从根本上解决IPv4地址不够用的问题。

7. 说一 ARP 协议的工作流程?

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

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

8. IP 地址和 MAC 地址都有什么作用呢?

  • MAC地址是数据链路层和物理层使用的地址,是写在网卡上的物理地址,用来定义网络设备的位置,不可变更。
  • IP地址是网络层和以上各层使用的地址,是一种逻辑地址。IP地址用来区别网络上的计算机。

9. 为什么已经有了 IP 地址,还需要有 MAC 地址呢?

  • 如果我们只使用MAC地址进行寻址的话,我们需要路由器记住每个MAC地址属于哪个子网,不然一次路由器收到数据包都要满世界寻找目的MAC地址。而我们知道MAC地址的长度为48位,也就是最多共有2的48次方个MAC地址,这就意味着每个路由器需要256T的内存,显然是不现实的。
  • 和MAC地址不同,IP地址是和地域相关的,在一个子网中的设备,我们给其分配的IP地址前缀都是一样的,这样路由器就能根据IP地址的前缀知道这个设备属于哪个子网,剩下的寻址就交给子网内部实现,从而大大减少了路由器所需要的内存。

10. 为什么有了 MAC 地址还需要有 IP 地址呢?

  • 只有当设备连入网络时,才能根据他进入了哪个子网来为其分配IP地址,在设备还没有IP地址的时候,或者在分配IP的过程中。我们需要MAC地址来区分不同的设备。
  • IP 地址可以比作为地址,MAC 地址为收件人,在一次通信过程中,两者是缺一不可的。

11. 简单说一 ICMP 协议的功能?

ICMP(Internet Control Message Protocol) ,网际控制报文协议。

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

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

12. 说一下 ping 的原理?

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

一般来说,ping 可以用来检测网络通不通。它是基于ICMP协议工作的。假设机器 A ping 机器 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 地址、发送 & 收到 & 丢失的分组数、往返时间的最小、最大 & 平均值

13. 什么是 TTL?TTL 的作用是什么?

TTL 是 Time To Live 的缩写,该字段指定 IP包被路由器丢弃之前允许通过的最大网段数量。(需要注意的是 TTL 与 DNS TTL 二者都是生存时间,前者指 ICMP 包的转发次数或跳数,后者指域名解析信息在DNS中的存在时间。)

TTL 的作用是限制 IP数据包在计算机网络中的存在的时间,以避免IP包在网络中的无限循环和收发,节省了网络资源,并能使IP包的发送者能收到告警消息。TTL的最大值是255,TTL的一个推荐值是64。

🛡️网络安全


1. 说说有哪些安全攻击?

网络安全攻击主要分为两种类型,被动攻击主动攻击

  • 被动攻击:是指攻击者从网络上窃听他人的通信内容,通常把这类攻击称为截获,被动攻击主要有两种形式:消息内容泄露攻击和流量分析攻击。由于攻击者没有修改数据,使得这种攻击很难被检测到。
  • 主动攻击:直接对现有的数据和服务造成影响,常见的主动攻击类型有:
    • 篡改:攻击者故意篡改网络上送的报文,甚至把完全伪造的报文传送给接收方。
    • 恶意程序:恶意程序种类繁多,包括计算机病毒、计算机蠕虫、特洛伊木马、后门入侵、流氓软件等等。
    • 拒绝服务Dos:攻击者向服务器不停地发送分组,使服务器无法提供正常服务。

2. DNS 劫持了解吗?

NS劫持即域名劫持,是通过将原域名对应的IP地址进行替换,从而使用户访问到错误的网站,或者使用户无法正常访问网站的一种攻击方式。

域名劫持往往只能在特定的网络范围内进行,范围外的DNS服务器能够返回正常的IP地址。攻击者可以冒充原域名所属机构,通过电子邮件的方式修改组织机构的域名注册信息,或者将域名转让给其它主持,并将新的域名信息保存在所指定的DNS服务器中,从而使用户无法对原域名来进行解析以访问目标地址。

DNS 劫持的步骤是什么?

  1. 获取要劫持的域名信息:攻击者会首先访问域名查询要劫持的站点的域名信息。
  2. 控制域名响应的E-Mail账号:在获取到域名信息后,攻击者通过暴力破解或者专门的方法破解公司注册域名时使用的E-mail账号所对应的密码,更高级的攻击者甚至能够直接对E-Mail进行信息窃取。
  3. 修改注册信息:当攻击者破解了E-Mail后,会利用相关的更改功能修改该域名的注册信息,包括域名拥有者信息,DNS服务器信息等。
  4. 使用E-Mail收发确认函:在修改完注册信息后,攻击者E-Mail在真正拥有者之前收到修改域名注册信息的相关确认信息,并回复确认修改文件,待网络公司恢复已成功修改信件后,攻击者便成功完成DNS劫持。

怎么应对DNS劫持?

  • 直接通过IP地址访问网站,避开DNS劫持
  • 由于域名劫持往往只能在特定的网络范围内进行,因此一些高级用户可以通过网络设置让DNS指向正常的域名服务器以实现对目标网址的正常访问,例如计算机首选DNS服务器的地址固定为8.8.8.8(这个也是解决 DNS 污染的一个方法)。

3. 什么是 CSRF 攻击?如何避免?

什么是 CSRF 攻击?

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

CSRF 是如何进行攻击的呢?

来看一个例子:

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

怎么应对 CSRF 攻击呢?

  • 检查 Referer 字段HTTP头中的Referer字段记录了该 HTTP 请求的来源地址。在通常情况下,访问一个安全受限页面的请求来自于同一个网站,而如果黑客要对其实施 CSRF攻击,他一般只能在他自己的网站构造请求。因此,可以通过验证Referer值来防御CSRF 攻击。
  • 添加校验 token以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有token或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。
  • 敏感操作多重校验对一些敏感的操作,除了需要校验用户的认证信息,还可以通过邮箱确认、验证码确认这样的方式多重校验。

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

  • DOS : (Denial of Service), 翻译过来就是拒绝服务, 一切能引起拒绝 行为的攻击都被称为 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 地址源做出大量回应,从而形成拒绝服务攻击。

如何防范DDoS?

1、屏蔽未经请求发送的DNS响应信息

一个典型的DNS交换信息是由请求信息组成的。DNS解析器会将用户的请求信息发送至DNS服务器中,在DNS服务器对查询请求进行处理之后,服务器会将响应信息返回给DNS解析器。但值得注意的是,响应信息是不会主动发送的。服务器在没有接收到查询请求之前,就已经生成了对应的响应信息,回应就被丢弃丢弃快速重传数据包。1.即便是在数据包丢失的情况下,任何合法的DNS客户端都不会在较短的时间间隔内向同一DNS服务器发送相同的DNS查询请求。2.如果从相同IP地址发送至同一目标地址的相同查询请求发送频率过高,这些请求数据包可丢弃。

2、启用TTL

如果DNS服务器已经将响应信息成功发送了,应该禁止服务器在较短的时间间隔内对相同的查询请求信息进行响应。1.对于一个合法的DNS客户端如果已经接收到了响应信息,就不会再次发送相同的查询请求。2.每一个响应信息都应进行缓存处理直到TTL过期。3.当DNS服务器遭遇大量查询请求时,可以屏蔽掉不需要的数据包。丢弃未知来源的DNS查询请求和响应数据通常情况下,攻击者会利用脚本来对目标进行分布式拒绝服务攻击(DDoS攻击),而且这些脚本通常是有漏洞的。因此,在服务器中部署简单的匿名检测机制,在某种程度上可以限制传入服务器的数据包数量。丢弃未经请求或突发的DNS请求这类请求信息很可能是由伪造的代理服务器所发送的,或是由于客户端配置错误或者是攻击流量。所以无论是哪一种情况,都应该直接丢弃这类数据包。非泛洪攻击 (non-flood) 时段,创建一个白名单,添加允许服务器处理的合法请求信息。白名单可以屏蔽掉非法的查询请求信息以及此前从未见过的数据包。这种方法能够有效地保护服务器不受泛洪攻击的威胁,也能保证合法的域名服务器只对合法的DNS查询请求进行处理和响应。

3、启动DNS客户端验证

伪造是DNS攻击中常用的一种技术。如果设备可以启动客户端验证信任状,便可以用于从伪造泛洪数据中筛选出非泛洪数据包。对响应信息进行缓存处理如果某一查询请求对应的响应信息已经存在于服务器的DNS缓存之中,缓存可以直接对请求进行处理。这样可以有效地防止服务器因过载而发生宕机。

很多请求中包含了服务器不具有或不支持的信息,我们可以进行简单的阻断设置,例如外部IP地址请求区域转换或碎片化数据包,直接将这类请求数据包丢弃。利用ACL,BCP38,及IP信誉功能的使用托管DNS服务器的任何企业都有用户轨迹的限制,当攻击数据包被伪造,伪造请求来自世界各地的源地址。设置一个简单的过滤器可阻断不需要的地理位置的IP地址请求或只允许在地理位置白名单内的IP请求。

还有一种情况,某些伪造的数据包可能来自与内部网络地址,可以利用BCP38通过硬件过滤也可以清除异常来源地址的请求。BCP38对于提供DNS解析的服务提供商也相当有用,可以避免用户向外发送攻击或受到内部地址请求的攻击,过滤用户并保证其数据传输。

4、提供余量带宽

如果服务器日常需要处理的DNS通信量达到了X Gbps,请确保流量通道不止是日常的量,有一定的带宽余量可以有利于处理大规模攻击。结语,目前针对DNS的攻击已成为最严重的网络威胁之一。目前越来越多的大型网站注重DNS保护这一块。为保障网站安全,保障网站利益,选择高防型的DNS为自己的域名进行解析已经迫在眉睫。

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

XSS 攻击也是比较常见,XSS,叫跨站脚本攻击(Cross-Site Scripting) ,因为会与层叠样式表 (Cascading Style Sheets, CSS) 的缩写混淆,因此有人将跨站脚本攻击缩写为 XSS。它指的是恶意攻击者往 Web 页面里插入恶意 html 代码,当用户浏览网页的时候,嵌入其中 Web 里面的 html 代码会被执行,从而达到恶意攻击用户的特殊目的。

XSS 攻击一般分三种类型:存储型 、反射型 、DOM 型 XSS

6. XSS是如何攻击的呢?

简单说,XSS的攻击方式就是想办法"教唆"用户的浏览器去执行一些这个网页中原本不存在的前端代码。

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

  1. 攻击者构造出特殊的 URL,其中包含恶意代码。
  2. 用户打开带有恶意代码的 URL 时,访问正常网站服务器
  3. 网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。
  4. 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行,请求恶意服务器,发送用户数据
  5. 攻击者就可以窃取用户的数据,以此冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

7. 如何解决 XSS 攻击问题?

  • 对输入进行过滤,过滤标签等,只允许合法值。
  • HTML 转义
  • 对于链接跳转,如<a href="xxx" 等,要校验内容,禁止以 script 开头的非法链接。
  • 限制输入长度

8. 对称加密和非对称加密之间有什么区别?

对称加密:指加密和解密使用同一密钥,优点是运算速度较快,缺点是如何安全将密钥传输给另一方。常见的对称加密算法有:DES、AES 等。

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

9. RSA和AES算法有什么区别?

  • RSA采用非对称加密的方式,采用公钥进行加密,私钥解密的形式。其私钥长度一般较长,由于需要大数的乘幂求模等运算,其运算速度较慢,不合适大量数据文件加密。
  • AES采用对称加密的方式,其秘钥长度最长只有256个比特,加密和解密速度较快,易于硬件实现。由于是对称加密,通信双方在进行数据传输前需要获知加密密钥。

10. 简单聊一下 SQL 注入?SQL 注入是怎么进行攻击的?

SQL注入是最经典的安全问题。无论你是前端开发还是后端开发,都必须掌握的。

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

那SQL 注入是怎么进行攻击的呢?

举个常见的业务场景:在web表单搜索框输入员工名字,然后后台查询出对应名字的员工。

这种场景下,一般都是前端页面,把一个名字参数name传到后台,然后后台通过SQL把结果查询出来

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

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

csharp 复制代码
select * from staff where name='' or '1'='1';

这个SQL会把所有的员工信息全都查出来了,酱紫就请求用户已经越权啦。请求者可以获取所有员工的信息,信息已经暴露了啦。

11. 如何预防 SQL 注入问题?

  1. 使用#{}而不是 ${}

在MyBatis中,使用 #{} 而不是 ${} ,可以很大程度防止sql注入。(Go 和 C++ 的 ORM 框架都有对应的解决方法,这里就不做过多的赘述了)

  • 因为 #{} 是一个参数占位符,对于字符串类型,会自动加上"",其他类型不加。由于Mybatis采用预编译,其后的参数不会再进行SQL编译,所以一定程度上防止SQL注入。
  • ${}是一个简单的字符串替换,字符串是什么,就会解析成什么,存在SQL注入风险
  1. 不要暴露一些不必要的日志或者安全信息,比如避免直接响应一些sql异常信息。
  • 如果SQL发生异常了,不要把这些信息暴露响应给用户,可以自定义异常进行响应
  1. ****不相信任何外部输入参数,过滤参数中含有的一些数据库关键词关键词
  • 可以加个参数校验过滤的方法,过滤union,or等数据库关键词
  1. 适当的权限控制
  • 在你查询信息时,先校验下当前用户是否有这个权限。比如说,实现代码的时候,可以让用户多传一个企业Id什么的,或者获取当前用户的session信息等,在查询前,先校验一下当前用户是否是这个企业下的等等,是的话才有这个查询员工的权限。

12. 简单聊一下防盗链

盗链是指服务提供商自己不提供服务的内容,通过技术手段(可以理解成爬虫)去获取其他网站的资源展示在自己的网站上。常见的盗链有以下几种:图片盗链、音频盗链、视频盗链等。

网站盗链会大量消耗被盗链网站的带宽,而真正的点击率也许会很小,严重损害了被盗链网站的利益。

被盗网站就自然会防盗链,可以通过经常更换图片名,也可以通过检测referer。因为正常用户访问一张图片一定是从自己的网站点击链接进去的,如果一个请求的referer是其他网站,就说明这是一个爬虫。

什么是 Referer?

这里的 Referer 指的是 HTTP 头部的一个字段,也称为 HTTP 来源地址(HTTP Referer),用来表示从哪儿链接到目前的网页,采用的格式是 URL。换句话说,借着 HTTP Referer 头部网页可以检查访客从哪里而来,这也常被用来对付伪造的跨网站请求。

盗链网站会针对性进行反盗链 ,可以通过在请求的headers中设置referer来绕过防盗链,我们现在使用爬虫抓取别人的网站也是这样。

什么是空 Referer,什么时候会出现空 Referer?

首先,我们对空 Referer 的定义为,Referer 头部的内容为空,或者,一个 HTTP 请求中根本不包含 Referer 头部。

那么什么时候 HTTP 请求会不包含 Referer 字段呢?根据 Referer 的定义,它的作用是指示一个请求是从哪里链接过来,那么当一个请求并不是由链接触发产生的,那么自然也就不需要指定这个请求的链接来源。

比如,直接在浏览器的地址栏中输入一个资源的 URL 地址,那么这种请求是不会包含 Referer 字段的,因为这是一个 "凭空产生" 的 HTTP 请求,并不是从一个地方链接过去的。


参考资料:

相关推荐
心软小念1 小时前
外包干了27天,技术退步明显。。。。。
软件测试·面试
芷栀夏3 小时前
如何在任何地方随时使用本地Jupyter Notebook无需公网IP
服务器·ide·tcp/ip·jupyter·ip
xserver26 小时前
ensp 基于EASY IP的公司出口链路配置
网络·tcp/ip·智能路由器
小k_不小6 小时前
C++面试八股文:指针与引用的区别
c++·面试
萧瑟其中~10 小时前
计算机网络:TCP/IP网络协议
网络协议·tcp/ip·计算机网络
IT 古月方源10 小时前
ensp 关于ARRP 的讲解 配置
运维·开发语言·网络·tcp/ip·智能路由器
林枫依依10 小时前
如何让Tplink路由器自身的IP网段 与交换机和电脑的IP网段 保持一致?
网络·tcp/ip·智能路由器
极客小张11 小时前
基于STM32的智慧农业控制系统设计:python可视化、UART、I2C、TCP/HTTP技术
python·stm32·单片机·物联网·tcp/ip·毕业设计·课程设计
上海运维Q先生11 小时前
面试题整理13----deployment和statefulset区别
运维·面试·kubernetes
ascarl201013 小时前
【Nginx系列】---Nginx配置tcp转发
运维·tcp/ip·nginx