计算机网络
概述
TCP/IP网络模型
网络接口层的传输单位是帧(frame),IP 层的传输单位是包(packet),TCP 层的传输单位是段(segment),HTTP 的传输单位则是消息或报文(message)。
从上往下讲
应用层
我们电脑或手机使用的应用软件都是在应用层实现。
应用层只需要专注于为用户提供应用功能,比如 HTTP、FTP、Telnet、DNS、SMTP
应用层是工作在操作系统中的用户态,传输层及以下则工作在内核态。
传输层
应用层的数据包会传给传输层,传输层(Transport Layer)是为应用层提供网络支持的。
在传输层会有两个传输协议,分别是 TCP 和 UDP。
当设备作为接收方时,传输层则要负责把数据包传给应用,但是一台设备上可能会有很多应用在接收或者传输数据,因此需要用一个编号将应用区分开来,这个编号就是端口。比如 80 端口通常是 Web 服务器用的,22 端口通常是远程登录服务器用的。
由于传输层的报文中会携带端口号,因此接收方可以识别出该报文是发送给哪个应用。
网络层
传输层的设计理念是简单、高效、专注,我们不希望传输层协议处理太多的事情,只需要服务好应用即可,让其作为应用间数据传输的媒介,帮助实现应用到应用的通信,而实际的传输功能就交给下一层,也就是网络层(Internet Layer)。
网络层负责将数据从一个设备传输到另一个设备,使用 IP 地址给设备进行编号。
只有一个单纯的 IP 地址虽然做到了区分设备,但是寻址起来就特别麻烦。因此,需要将IP 地址分成两种意义:
- 一个是网络号,负责标识该 IP 地址是属于哪个「子网」的;
- 一个是主机号,负责标识同一「子网」下的不同主机;
这需要配合子网掩码才能算出 IP 地址 的网络号和主机号。
数据链路层
网络接口层主要为网络层提供 [链路级别] 传输的服务,负责在以太网、WiFi 这样的底层网络上发送原始数据包,工作在网卡这个层次,使用 MAC 地址来标识网络上的设备。
MAC 头部是以太网使用的头部,它包含了接收方和发送方的 MAC 地址等信息,我们可以通过 ARP 协议获取对方的 MAC 地址。
以太网在判断网络包目的地时和 IP 的方式不同,因此必须采用相匹配的方式才能在以太网中将包发往目的地,而 MAC 头部就是干这个用的,所以,在以太网进行通讯要用到 MAC 地址。
应用层:HTTP协议
HTTP 基本概念
概念
HTTP 是超文本传输协议,也就是HyperText Transfer Protocol。
它可以拆成三个部分:
-
超文本
HTTP 传输的内容是「超文本」。
「文本」,在互联网早期的时候只是简单的字符文字,而现在图片、视频、压缩包等,在 HTTP 眼里这些都算作「文本」。
「超文本」,它就是超越了普通文本的文本,它是文字、图片、视频等的混合体,最关键有超链接,能从一个超文本跳转到另外一个超文本。
HTML 就是最常见的超文本了,它本身只是纯文字文件,但内部用很多标签定义了图片、视频等的链接,再经过浏览器的解释,呈现给我们的就是一个文字、有画面的网页了。
-
传输
我们在上网冲浪时,浏览器是请求方 A,百度网站就是应答方 B。双方约定用 HTTP 协议来通信。数据虽然是在 A 和 B 之间传输,但允许中间有中转或接力。
而在 HTTP 里,需要中间人遵从 HTTP 协议,只要不打扰基本的数据传输,就可以添加任意额外的东西。
-
协议
针对 HTTP 协议,我们可以这么理解。
HTTP 是一个用在计算机世界里的协议。它使用计算机能够理解的语言确立了一种计算机之间交流通信的规范,以及相关的各种控制和错误处理方式。
常见状态码
1xx
类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少。
2xx
类状态码表示服务器成功处理了客户端的请求,也是我们最愿意看到的状态。
-
「200 OK」是最常见的成功状态码,表示一切正常。如果是非
HEAD
请求,服务器返回的响应头都会有 body 数据。 -
「204 No Content」也是常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据。
-
「206 Partial Content」是应用于 HTTP 分块下载或断点续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态。
3xx
类状态码表示客户端请求的资源发生了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向。
- 「301 Moved Permanently」表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。
- 「302 Found」表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。
301 和 302 都会在响应头里使用字段 Location
,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。
- 「304 Not Modified」不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,也就是告诉客户端可以继续使用缓存资源,用于缓存控制。
4xx
类状态码表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义。
-
「400 Bad Request」表示客户端请求的报文有错误,但只是个笼统的错误。
-
「403 Forbidden」表示服务器禁止访问资源,并不是客户端的请求出错。
-
「404 Not Found」表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。
5xx
类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码。
- 「500 Internal Server Error」与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。
- 「501 Not Implemented」表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。
- 「502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
- 「503 Service Unavailable」表示服务器当前很忙,暂时无法响应客户端,类似“网络服务正忙,请稍后重试”的意思。
常见字段
-
Host 字段
客户端发送请求时,用来指定服务器的域名。
Host: www.A.com
-
Content-Length 字段
服务器在返回数据时,会有
Content-Length
字段,表明本次回应的数据长度。Content-Length: 1000
-
Connection 字段
Connection
字段最常用于客户端要求服务器使用「HTTP 长连接」机制,以便其他请求复用。HTTP 长连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。
HTTP/1.1 版本的默认连接都是长连接,但为了兼容老版本的 HTTP,需要指定
Connection
首部字段的值为Keep-Alive
。Connection: Keep-Alive
-
Content-Type 字段
Content-Type
字段用于服务器回应时,告诉客户端,本次数据是什么格式。Content-Type: text/html; Charset=utf-8
上面的类型表明,发送的是网页,而且编码是UTF-8。
-
Content-Encoding 字段
Content-Encoding
字段说明数据的压缩方法。表示服务器返回的数据使用了什么压缩格式。Content-Encoding: gzip
Get 与 Post
GET 的语义是从服务器获取指定的资源
POST 的语义是根据请求负荷(报文body)对指定的资源做出处理
1.OSI 的七层模型分别是?各自的功能是什么?
2.一次完整的HTTP请求过程
- URL解析:浏览器会解析输入的URL,包括协议(如HTTP),域名或IP地址,端口号(如果未指定,默认为80),以及路径和查询参数等。
- DNS解析:浏览器会查询域名对应的IP地址。首先,浏览器会检查本地缓存中是否存在已解析的IP地址,如果存在且没有过期,就直接使用该IP地址。否则,浏览器会向本地DNS缓存(如操作系统的hosts文件)查询IP地址,如果还没有找到,则会向DNS服务器发送DNS查询请求,获取域名对应的IP地址。
- 建立TCP连接:使用HTTP协议的默认端口(一般为80),浏览器向服务器发起TCP连接请求。这个过程通过三次握手进行,确保客户端与服务器之间建立可靠的连接。
- 发送HTTP请求:浏览器向服务器发送HTTP请求,请求方式可以是GET、POST等。同时,还会发送一些请求头部信息,包括请求方法、请求的URL、浏览器类型等。如果是POST请求,还会在请求头部中包含请求体的内容。
- 服务器处理请求:服务器接收到HTTP请求后,会根据请求的URL和方法等信息,通过对应的处理程序或脚本来处理请求。服务器可能会处理并返回请求的资源内容,或者执行一些服务器端的操作。
- 服务器发送响应:服务器处理完请求后,会生成HTTP响应,包括响应状态码、响应头部和响应体等。响应状态码表示请求的处理结果,如200表示成功,404表示资源不存在等。
- 接收并解析响应:浏览器接收到服务器的响应后,会先对响应进行解析,包括解析响应头部和响应体等。
- 渲染页面:浏览器会根据接收到的响应内容,解析HTML、CSS和JavaScript等文件,构建DOM树、CSSOM树和渲染树,然后将页面进行渲染显示。
- 关闭TCP连接:当浏览器完成页面渲染后,会关闭与服务器的TCP连接。此时,浏览器可以继续执行其他操作,如点击链接、提交表单等。
3.DNS
DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。
工作原理
- 如果本地的hosts文件没有能得到对应的ip地址,浏览器会发出一个dns请求到本地dns服务器,本地dns服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动等。
- 查询你输入的网址的DNS请求到达本地DNS服务器之后,本地DNS服务器会首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果,此过程是递归的方式进行查询。如果没有,本地DNS服务器还要向DNS根服务器进行查询。
- 本地DNS服务器继续向域服务器发出请求,在这个例子中,请求的对象是.com域服务器。.com域服务器收到请求之后,也不会直接返回域名和IP地址的对应关系,而是告诉本地DNS服务器,你的域名的解析服务器的地址。
- 最后,本地DNS服务器向域名的解析服务器发出请求,这时就能收到一个域名和IP地址对应关系,本地DNS服务器不仅要把IP地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时,可以直接返回结果,加快网络访问。
4.为什么域名解析用UDP协议
因为UDP快啊!UDP的DNS协议只要一个请求、一个应答就好了。
而使用基于TCP的DNS协议要三次握手、发送数据以及应答、四次挥手,但是UDP协议传输内容不能超过512字节。
不过客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。
5.为什么区域传送用TCP协议
因为TCP协议可靠性好啊!
你要从主DNS上复制内容啊,你用不可靠的UDP? 因为TCP协议传输的内容大啊,你用最大只能传512字节的UDP协议?万一同步的数据大于512字节,你怎么办?所以用TCP协议比较好!
6.HTTP长连接和短连接
在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。
而从HTTP/1.1起,默认使用长连接,用以保持连接特性。
长连接适用于频繁通信、实时数据传输、需要较快响应速度的应用,如实时聊天、即时通讯。短连接适用于请求并不频繁、响应时间对性能要求不高的应用,如一次性下载或获取静态资源。
7.TCP粘包/拆包
TCP粘包的原因是由于TCP为了提高传输效率,会将发送方的多个小的数据包尽量合并成一个大的数据包进行传输。这样在接收方可能会把多个数据包当作一个大的数据包来处理,导致粘包。
TCP拆包的原因是由于TCP为了保证数据的完整性,可能会将大的数据包拆分成多个小的数据包进行传输。这样在接收方可能会把一个数据包拆分成多个小的数据包来处理,导致拆包。
解决TCP粘包和拆包问题的方法有以下几种:
- 定长解决法:发送方发送固定长度的数据包,接收方按照固定长度进行拆包和处理。这种方法简单直接,但是对于不固定长度的数据包处理不方便。
- 分割符解决法:发送方在数据包之间插入一个特殊的分隔符,接收方根据分隔符来拆分数据包。这种方法适用于数据包中不会出现分隔符的情况,但是如果出现分隔符在数据包中的情况会导致拆包错误。
- 消息长度解决法:发送方在每个数据包中包含数据包的长度信息,接收方根据长度信息来拆包和处理。这种方法较为常用,但是在传输大文件等情况下,长度信息可能会占用较多的额外字节。
- 使用专用协议解决法:可以自定义一种专用的协议,用于在数据包中标识和区分不同的数据块。
8.为什么服务器会缓存这一项功能?如何实现的?
原因
- 缓解服务器压力;
- 降低客户端获取资源的延迟:缓存通常位于内存中,读取缓存的速度更快。并且缓存服务器在地理位置上也有可能比源服务器来得近,例如浏览器缓存。
实现方法
- 让代理服务器进行缓存;
- 让客户端浏览器进行缓存。
9.HTTP请求方法
HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。
序 号 | 方法 | 描述 |
---|---|---|
1 | GET | 请求指定的页面信息,并返回实体主体。 |
2 | HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
3 | POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。 |
4 | PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
5 | DELETE | 请求服务器删除指定的页面。 |
6 | CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。 |
7 | OPTIONS | 允许客户端查看服务器的性能。 |
8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
9 | PATCH | 是对 PUT 方法的补充,用来对已知资源进行局部更新 。 |
10.GET 和 POST 的区别
本质区别:GET是幂等的,而POST不是幂等的
- 数据传递方式:GET 方法将数据作为URL的一部分进行传递,以查询字符串的形式出现在URL的末尾。而 POST 方法将数据通过请求的正文进行传递,数据不会显示在URL中。
- 传递数据大小限制:由于GET方法将数据作为URL的一部分,常见的浏览器限制URL长度为2048个字符。而POST方法将数据放在请求的正文中,数据大小没有限制。
- 数据的安全性:GET 方法的数据以明文形式出现在URL中,对于敏感数据或密码等需要保密的信息不适合使用GET方法传递。POST 方法将数据放在请求的正文中,相对来说比GET方法更安全。
- 客户端缓存:GET 方法会被浏览器缓存,因为GET方法一般只用于获取数据,不会对服务器的数据进行修改。而POST方法会被浏览器标记为不可缓存,因为POST方法常用于提交表单,对服务器的数据进行修改。
GET产生一个TCP数据包,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
POST产生两个TCP数据包,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
12.一个 TCP 连接中 HTTP 请求发送可以一起发送么
HTTP/1.1 存在一个问题,单个 TCP 连接在同一时刻只能处理一个请求,意思是说:两个请求的生命周期不能重叠,任意两个 HTTP 请求从开始到结束的时间在同一个 TCP 连接里不能重叠。
在 HTTP/1.1 存在 Pipelining 技术可以完成这个多个请求同时发送,但是由于浏览器默认关闭,所以可以认为这是不可行的。
在 HTTP2 中由于 Multiplexing 特点的存在,多个 HTTP 请求可以在同一个 TCP 连接中并行进行。
那么在 HTTP/1.1 时代,浏览器是如何提高页面加载效率的呢?主要有下面两点:
- 维持和服务器已经建立的 TCP 连接,在同一连接上顺序处理多个请求。
- 和服务器建立多个 TCP 连接。
13.浏览器对同一 Host 建立 TCP 连接到的数量有没有限制?
有。Chrome 最多允许对同一个 Host 建立六个 TCP 连接。不同的浏览器有一些区别。
在 HTTP/1.1 时代,没有多路传输的情况下,当浏览器拿到一个有几十张图片的网页时,它需要使用串行方式来加载这些图片。
为了解决这个问题,HTTP/2 协议引入了多路传输机制,可以同时发送多个请求和响应,使得浏览器可以并行处理多个资源,提高了网页的加载速度和性能。
14.DNS负载均衡
DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将客户端的访问引导到不同的机器上去,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的。例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等。
15.HTTPS和HTTP的区别
- 安全性:HTTPS 是基于 HTTP 协议的加密协议,通过使用 SSL 或 TLS 加密协议对数据进行加密和身份认证。这意味着在使用 HTTPS 连接时,数据传输是加密的,可以保护用户的隐私和数据安全。而 HTTP 不对数据进行加密,传输的数据是明文的。
- 默认端口:HTTP 使用的是80端口进行通信,而 HTTPS 使用的是443端口进行通信。
- 证书验证:HTTPS 使用证书对服务器进行身份验证,用户可以根据证书验证服务器的真实性。而 HTTP 不进行服务器身份验证,无法验证服务器的真实性。证书需要费用
- 效率:由于 HTTPS 在通信过程中需要进行加密解密操作,相比于 HTTP,HTTPS 会增加一定的通信开销和延迟时间,所以 HTTPS 通信相对更加低效。
16.什么是SSL/TLS ?
SSL/TLS协议的基本思路是采用公钥加密法,也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。
客户端和服务器之间的通信会经历以下步骤:
- 客户端发送一个连接请求到服务器,并请求建立 SSL/TLS 连接。
- 服务器会发送包含公钥的数字证书给客户端。证书由受信任的第三方机构(CA,Certificate Authority)签名,用于验证服务器的身份。服务端还保存着对应的私钥。
- 客户端验证服务器的证书,包括检查证书的有效性和真实性。如果证书可信,则继续进行握手。
- 客户端生成一个随机数,利用服务器的公钥进行加密,并发送给服务器。
- 服务器利用私钥解密客户端发送的随机数。
- 客户端和服务器使用这个共享的随机数生成对称密钥(session key),用于加密和解密之后的通信数据。
- 客户端和服务器之间的通信数据被加密,并通过 SSL/TLS 连接传输。
上述过程通过非对称加密的方式安全地交换对称加密的密钥,然后使用对称加密加密大量数据,实现了加密的安全性和效率的统一。
17.如何保证公钥不被篡改?
将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。
18.Cookie
Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器之后向同一服务器再次发起请求时被携带上,用于告知服务端两个请求是否来自同一浏览器。由于之后每次请求都会需要携带 Cookie 数据,因此会带来额外的性能开销(尤其是在移动环境下)。
cookie 的出现是因为 HTTP 是无状态的一种协议,换句话说,服务器记不住你,可能你每刷新一次网页,就要重新输入一次账号密码进行登录。这显然是让人无法接受的,cookie 的作用就好比服务器给你贴个标签,然后你每次向服务器再发请求时,服务器就能够 cookie 认出你。
cookie可用于:
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
Cookie在客户端的保存形式可以有两种,一种是会话Cookie,一种是持久Cookie。
会话Cookie就是将服务器返回的Cookie字符串保持在内存中,关闭浏览器之后自动销毁。
持久Cookie则是存储在客户端磁盘上,其有效时间在服务器响应头中被指定,在有效期内,客户端再次请求服务器时都可以直接从本地取出。需要说明的是,存储在磁盘中的Cookie是可以被多个浏览器代理所共享的。
19.Session
Session是在服务器端创建和存储的用户会话对象。在用户访问网站时,服务器会为每个用户创建一个唯一的Session对象,并为其分配一个唯一的Session ID。服务器将Session ID作为Cookie发送给客户端,并且在后续的请求中通过Session ID来识别用户。
利用 Session 存储在服务器端,存储在服务器端的信息更加安全。Session 可以存储在服务器上的文件、数据库或者内存中,也可以将 存储在 Redis 这种内存型数据库中,效率会更高。
20.Session和cookie应该如何去选择(适用场景)?
-
Cookie 只能存储 ASCII 码字符串,而 Session 则可以存储任何类型的数据,因此在考虑数据复杂性时首选 Session;
-
Cookie 存储在浏览器中,容易被恶意查看。如果非要将一些隐私数据存在 Cookie 中,可以将 Cookie 值进行加密,然后在服务器进行解密;
-
对于大型网站,如果用户所有的信息都存储在 Session 中,那么开销是非常大的,因此不建议将所有的用户信息都存储到 Session 中。
21.SQL注入攻击
攻击者在HTTP请求中注入恶意的SQL代码,服务器使用参数构建数据库SQL命令时,恶意SQL被一起构造,并在数据库中执行。
用户登录,输入用户名 lianggzone,密码 ‘ or ‘1’=’1 ,如果此时使用参数构造的方式,就会出现 select * from user where name = ‘lianggzone’ and password = ‘’ or ‘1’=‘1’ 不管用户名和密码是什么内容,使查询出来的用户列表不为空。
如何防范SQL注入攻击?
使用预编译的PrepareStatement是必须的,但是一般我们会从两个方面同时入手。
Web端 :1)有效性检验。 2)限制字符串输入的长度。
服务端: 1)不用拼接SQL字符串。 2)使用预编译的PrepareStatement。 3)有效性检验。(为什么服务端还要做有效性检验?第一准则,外部都是不可信的,防止攻击者绕过Web端请求) 4)过滤SQL需要的参数中的特殊字符。比如单引号、双引号。
22.什么是RARP?
反向地址转换协议,网络层协议,RARP与ARP工作方式相反。
RARP使只知道自己硬件地址的主机能够知道其IP地址。
原理:
(1)主机从网卡上读取MAC地址,然后在网络上发送一个RARP请求的广播数据包,请求RARP服务器回复该主机的IP地址。
(2)RARP服务器收到了RARP请求数据包,为其分配IP地址,并将RARP回应发送给主机。
(3)PC1收到RARP回应后,就使用得到的IP地址进行通讯。
23.端口有效范围
UDP和TCP报头使用两个字节存放端口号,所以端口号的有效范围是从0到65535。
0-1023为知名端口号,比如其中HTTP是80,FTP是20(数据端口)、21(控制端口)
动态端口的范围是从1024到65535。
24.为何需要把 TCP/IP 协议栈分成 5 层(或7层)?
分层的好处:
①隔层之间是独立的
②灵活性好
③结构上可以分隔开
④易于实现和维护
⑤能促进标准化工作。
25.HTTP中缓存的私有和共有字段?
Cache-Control: public
private 指令规定了将资源作为私有缓存,只能被单独用户使用,一般存储在用户浏览器中。
public 指令规定了将资源作为公共缓存,可以被多个用户使用,一般存储在代理服务器中。
26.GET 方法参数写法是固定的吗?
在约定中,我们的参数是写在 ? 后面,用 & 分割。
我们知道,解析报文的过程是通过获取 TCP 数据,用正则等工具从数据中获取 Header 和 Body,从而提取参数。
也就是说,我们可以自己约定参数的写法,只要服务端能够解释出来就行,万变不离其宗。
27.GET 方法的长度限制是怎么回事?
首先说明一点,HTTP 协议没有 Body 和 URL 的长度限制,对 URL 限制的大多是浏览器和服务器的原因。
浏览器原因就不说了。
服务器是因为处理长 URL 要消耗比较多的资源,为了性能和安全(防止恶意构造长 URL 来攻击)考虑,会给 URL 长度加限制。
28.POST 方法比 GET 方法安全?
从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,只要在网络节点上捉包,就能完整地获取数据报文。
要想安全传输,就只有加密,也就是 HTTPS。
29.POST 方法会产生两个 TCP 数据包?你了解吗?
有些文章中提到,POST 会将 header 和 body 分开发送,先发送 header,服务端返回 100 状态码再发送 body。
HTTP 协议中没有明确说明 POST 会产生两个 TCP 数据包,而且实际测试(Chrome)发现,header 和 body 不会分开发送。
所以,header 和 body 分开发送是部分浏览器或框架的请求方法,不属于 post 必然行为。
30.DDos 攻击了解吗?
客户端向服务端发送请求链接数据包,服务端向客户端发送确认数据包,客户端不向服务端发送确认数据包,服务器一直等待来自客户端的确认,没有彻底根治的办法,除非不使用TCP
DDos 预防: 1)限制同时打开SYN半链接的数目 2)缩短SYN半链接的Time out 时间 3)关闭不必要的服务
31.MTU和MSS分别是什么?
MTU:maximum transmission unit,最大传输单元,由硬件规定,如以太网的MTU为1500字节。
MSS:maximum segment size,最大分节大小,为TCP数据包每次传输的最大数据分段大小,一般由发送端向对端TCP通知对端在每个分节中能发送的最大TCP数据。
MSS值为MTU值减去IPv4 Header(20 Byte)和TCP header(20 Byte)得到。(减去传输层和网络层的头部,得到数据链路层的最大传输单元)
MTU是物理网络层的最大传输单位,而MSS是在TCP连接层中传的最大输单位。
32.HTTP中有个缓存机制,但如何保证缓存是最新的呢?
使用缓存控制头
只是其中一种办法
Cache-Control: max-age=31536000
max-age 指令出现在请求报文,并且缓存资源的缓存时间小于该指令指定的时间,那么就能接受该缓存。
max-age 指令出现在响应报文,表示缓存资源在缓存服务器中保存的时间。
33.TCP头部中有哪些信息?
- 序号(32bit):传输方向上字节流的字节编号。初始时序号会被设置一个随机的初始值(ISN),之后每次发送数据时,序号值 = ISN + 数据在整个字节流中的偏移。假设A -> B且ISN = 1024,第一段数据512字节已经到B,则第二段数据发送时序号为1024 + 512。用于解决网络包乱序问题。
- **确认号(**32bit):接收方对发送方TCP报文段的响应,其值是收到的序号值 + 1。
- 首部长(4bit):标识首部有多少个4字节 * 首部长,最大为15,即60字节。
- 标志位(6bit):
- URG:标志紧急指针是否有效。
- ACK:标志确认号是否有效(确认报文段)。用于解决丢包问题。
- PSH:提示接收端立即从缓冲读走数据。
- RST:表示要求对方重新建立连接(复位报文段)。
- SYN:表示请求建立一个连接(连接报文段)。
- FIN:表示关闭连接(断开报文段)。
- 窗口(16bit):接收窗口。用于告知对方(发送方)本方的缓冲还能接收多少字节数据。用于解决流控。
- 校验和(16bit):接收端用CRC检验整个报文段有无损坏。
34.常见TCP的连接状态
握手状态
- CLOSED:初始状态。
- **LISTEN:**服务器处于监听状态。
- SYN_SEND:客户端socket执行CONNECT连接,发送SYN包,进入此状态。
- **SYN_RECV:**服务端收到SYN包并发送服务端SYN包,进入此状态。
- 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响应,进入此状态。
- TIME_WAIT:客户端收到服务端的FIN包,并立即发出ACK包做最后的确认,在此之后的2MSL时间称为TIME_WAIT状态。
35.应用层常见协议知道多少?
HTTP | 超文本传输协议 | 80 | TCP |
---|---|---|---|
HTTPS | 超文本传输安全协议 | 443 | TCP |
Telnet | 远程登录服务的标准协议 | 23 | TCP |
FTP | 文件传输协议 | 20传输和21连接 | TCP |
TFTP | 简单文件传输协议 | 69 | UDP |
SMTP | 简单邮件传输协议(发送用) | 25 | TCP |
POP | 邮局协议(接收用) | 110 | TCP |
DNS | 域名解析服务 | 53 | 服务器间进行域传输的时候用TCP 客户端查询DNS服务器时用 UDP |
36.浏览器在与服务器建立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开?
在 HTTP/1.0 中,一个服务器在发送完一个 HTTP 响应后,会断开 TCP 链接。但是这样每次请求都会重新建立和断开 TCP 连接,代价过大。所以虽然标准中没有设定,某些服务器对 Connection: keep-alive 的 Header 进行了支持。意思是说,完成这个 HTTP 请求之后,不要断开 HTTP 请求使用的 TCP 连接。这样的好处是连接可以被重新使用,之后发送 HTTP 请求的时候不需要重新建立 TCP 连接,以及如果维持连接,那么 SSL 的开销也可以避免。
持久连接:既然维持 TCP 连接好处这么多,HTTP/1.1 就把 Connection 头写进标准,并且默认开启持久连接,除非请求中写明 Connection: close,那么浏览器和服务器之间是会维持一段时间的 TCP 连接,不会一个请求结束就断掉。
默认情况下建立 TCP 连接不会断开,只有在请求报头中声明 Connection: close 才会在请求完成后关闭连接。
37.三次握手相关内容
-
初始状态:客户端处于
closed(关闭)
状态,服务器处于listen(监听)
状态。 -
第一次握手:客户端发送请求报文将
SYN = 1
同步序列号和初始化序列号seq = x
发送给服务端,发送完之后客户端处于SYN_Send
状态。(客户端角度:我现在什么都不知道)
(服务器角度:我接受ok,你发送ok)
-
第二次握手:服务端受到
SYN
请求报文之后,如果同意连接,会以自己的同步序列号SYN(服务端) = 1
、初始化序列号seq = y
和确认序列号(期望下次收到的数据包)ack = x+ 1
以及确认号ACK = 1
报文作为应答,服务器为SYN_Receive
状态。(客户端角度:我发送和接受ok,服务端发送和接受ok,好了我已经准备就绪了)
(服务器角度:我接受ok,你发送ok)
-
第三次握手:客户端接收到服务端的
SYN + ACK
之后,知道可以下次可以发送了下一序列的数据包了,然后发送同步序列号ack = y + 1
和数据包的序列号seq = x + 1
以及确认号ACK = 1
确认包作为应答,客户端转为established
状态。(服务器角度:我发送和接受ok,客户端发送和接受ok)
为什么不能两次握手?
第一个原因:服务器角只知道自身接受能力ok,客户端发送能力ok,但无法确认自身的发送能力和客户端的接受能力
第二个原因:历史连接问题
如果采用两次握手建立 TCP 连接的场景下,服务端在向客户端发送数据前,并没有阻止掉历史连接,导致服务端建立了一个历史连接,又白白发送了数据,妥妥地浪费了服务端的资源。
38.什么是半连接队列?
服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列。
ISN = M + F(localhost, localport, remotehost, remoteport)(M为计数器),F为哈希算法,
还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。
39.ISN(Initial Sequence Number)是固定的吗?
ISN随时间而变化,因此每个连接都将具有不同的ISN,ISN是一个有可以看作是一个32比特的计数器,但并不是简单的计数器,大概每4ms加1 。
三次握手的其中一个重要功能是客户端和服务端交换 ISN(Initial Sequence Number),以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的,攻击者很容易猜出后续的确认号,因此 ISN 是动态生成的。
40.SYN攻击
SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。
常见的防御 SYN 攻击的方法有如下几种:
- 缩短超时(SYN Timeout)时间
- 增加最大半连接数
- 过滤网关防护
- SYN cookies技术
41.四次挥手相关内容
-
初始化状态:客户端和服务端都在连接状态,接下来开始进行四次分手断开连接操作。
-
第一次分手:第一次分手无论是客户端还是服务端都可以发起,因为 TCP 是全双工的。假如客户端发送的数据已经发送完毕,发送FIN = 1 告诉服务端,客户端所有数据已经全发完了,服务端你可以关闭接收了,但是如果你们服务端有数据要发给客户端,客户端照样可以接收的。此时客户端处于FIN = 1等待服务端确认释放连接状态。
-
第二次分手:服务端接收到客户端的释放请求连接之后,知道客户端没有数据要发给自己了,然后服务端发送ACK = 1告诉客户端收到你发给我的信息,此时服务端处于 CLOSE_WAIT 等待关闭状态。
-
第三次分手:此时服务端向客户端把所有的数据发送完了,然后发送一个FIN = 1,用于告诉客户端,服务端的所有数据发送完毕,客户端你也可以关闭接收数据连接了。此时服务端状态处于LAST_ACK状态,来等待确认客户端是否收到了自己的请求。
-
第四次分手:此时如果客户端收到了服务端发送完的信息之后,就发送ACK = 1,告诉服务端,客户端已经收到了你的信息。有一个 2 MSL 的延迟等待。
42.2MSL等待状态
TIME_WAIT状态也称为2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime),它是任何报文段被丢弃前在网络内的最长时间。这个时间是有限的,因为TCP报文段以IP数据报在网络内传输,而IP数据报则有限制其生存时间的TTL字段。
假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。
43.对称密钥加密的优缺点
对称密钥加密(Symmetric-Key Encryption),加密和解密使用同一密钥。
- 优点:运算速度快
- 缺点:无法安全地将密钥传输给通信方
44.非对称密钥加密的优缺点
非对称密钥加密,又称公开密钥加密(Public-Key Encryption),加密和解密使用不同的密钥。
公开密钥所有人都可以获得,通信发送方获得接收方的公开密钥之后,就可以使用公开密钥进行加密,接收方收到通信内容后使用私有密钥解密。
- 优点:可以更安全地将公开密钥传输给通信发送方;
- 缺点:运算速度慢。
45.HTTPS采用的加密方式有哪些?是对称还是非对称?
HTTPS 采用混合的加密机制,使用非对称密钥加密用于传输对称密钥来保证传输过程的安全性,之后使用对称密钥加密进行通信来保证通信过程的效率。
46.SSL中的认证中的证书是什么?
47.HTTP如何禁用缓存?如何确认缓存?
HTTP/1.1 通过 Cache-Control 首部字段来控制缓存。
禁止进行缓存
no-store 指令规定不能对请求或响应的任何一部分进行缓存。
Cache-Control: no-store
强制确认缓存
no-cache 指令规定缓存服务器需要先向源服务器验证缓存资源的有效性,只有当缓存资源有效时才能使用该缓存对客户端的请求进行响应。
Cache-Control: no-cache
48.GET与POST传递数据的最大长度能够达到多少呢?
49.网络层常见协议
协议 | 名称 | 作用 |
---|---|---|
IP | 网际协议 | IP协议不但定义了数据传输时的基本单元和格式,还定义了数据报的递交方法和路由选择 |
ICMP | Internet控制报文协议 | ICMP就是一个“错误侦测与回报机制”,其目的就是让我们能够检测网路的连线状况﹐也能确保连线的准确性,是ping和traceroute的工作协议 |
RIP | 路由信息协议 | 使用“跳数”(即metric)来衡量到达目标地址的路由距离 |
IGMP | Internet组管理协议 | 用于实现组播、广播等通信 |
50.TCP四大拥塞控制算法
慢热启动算法 – Slow Start
所谓慢启动,也就是TCP连接刚建立,缓慢地提速,试探网络的承受能力,以免直接扰乱了网络通道的秩序。
慢启动算法:
- 连接建好的开始先初始化拥塞窗口cwnd大小为1,表明可以传一个MSS大小的数据。
- 每当收到一个ACK,cwnd大小加一,呈线性上升。
- 每当过了一个往返延迟时间RTT(Round-Trip Time),cwnd大小直接乘以2,呈指数上升。
- 还有一个ssthresh(slow start threshold),是一个上限,当cwnd >= ssthresh时,就会进入“拥塞避免算法”
拥塞避免算法 – Congestion Avoidance
当拥塞窗口大小cwnd大于等于慢启动阈值ssthresh后,就进入拥塞避免算法。算法如下:
- 收到一个ACK,则cwnd = cwnd + 1 / cwnd
- 每当过了一个往返延迟时间RTT,cwnd大小加1。
过了慢启动阈值后,拥塞避免算法可以避免窗口增长过快导致窗口拥塞,而是缓慢的增加调整到网络的最佳值
快速重传 - Fast Retransmit
早期的TCP Tahoe算法如果发生超时重传RTO,TCP会重传数据包,并且执行以下步骤
- ssthresh = cwnd / 2.
- cwnd重置为1
- 进入慢启动过程
这种算法由于一丢包就一切重来,导致cwnd又重置为1,十分不利于网络数据的稳定传递。
TCP Reno算法进行了优化。当收到三个重复确认ACK时,会立即重传被确认丢失的数据包,而不需要等待超时(超时重传)。
快速恢复算法 – Fast Recovery
当发送方接收到3个重复的确认信息,触发快速重传后,它并不会立即进入慢启动阶段。快速恢复算法的逻辑如下:
- cwnd大小缩小为当前的一半
- ssthresh设置为缩小后的cwnd大小
- 然后进入拥塞避免算法。
51.为何快速重传是选择3次ACK
两次duplicated ACK时很可能是乱序造成的!
三次duplicated ACK时很可能是丢包造成的!
四次duplicated ACK更更更可能是丢包造成的
包的丢失原因:
1)包checksum 出错
2)网络拥塞
3)网络断,包括路由重收敛
发送方无法判断是哪一种情况,于是采用最笨的办法,就是将自己的发送速率减半,即CWND 减为1/2,这样的方法对2是有效的,可以缓解网络拥塞,3则无所谓,反正网络断了,无论发快发慢都会被丢;但对于1来说,丢包是因为偶尔的出错引起,一丢包就对半减速不合理。
52.对于FIN_WAIT_2,CLOSE_WAIT状态和TIME_WAIT状态?
-
FIN_WAIT_2:
- 半关闭状态。
- 发送断开请求一方还有接收数据能力,但已经没有发送数据能力。
-
CLOSE_WAIT状态:
- 被动关闭连接一方接收到FIN包会立即回应ACK包表示已接收到断开请求。
- 被动关闭连接一方如果还有剩余数据要发送就会进入CLOSE_WAIT状态。
-
TIME_WAIT状态:
- 又叫2MSL等待状态。
- 如果客户端直接进入CLOSED状态,如果服务端没有接收到最后一次ACK包会在超时之后重新再发FIN包,此时因为客户端已经CLOSED,所以服务端就不会收到ACK而是收到RST。所以TIME_WAIT状态目的是防止最后一次握手数据没有到达对方而触发重传FIN准备的。
- 在2MSL时间内,同一个socket不能再被使用,否则有可能会和旧连接数据混淆(如果新连接和旧连接的socket相同的话)。
53.流量控制原理
-
目的是接收方通过TCP头窗口字段告知发送方本方可接收的最大数据量,用以解决发送速率过快导致接收方不能接收的问题。所以流量控制是点对点控制。
-
TCP是双工协议,双方可以同时通信,所以发送方接收方各自维护一个发送窗口和接收窗口。
- 发送窗口:用来限制发送方可以发送的数据大小,其中发送窗口的大小由接收端返回的TCP报文段中窗口字段来控制,接收方通过此字段告知发送方自己的缓冲(受系统、硬件等限制)大小。
- 接收窗口:用来标记可以接收的数据大小。
如果发送方收到接收方的零窗口通知,会启动持续计时器,计时器超时后会向接收方发送零窗口探测报文,防止出现死锁等待情况。
54.建立TCP服务器的各个系统调用过程
connect连接过程
55.TCP 协议如何保证可靠传输?
- 确认和重传:接收方收到报文就会确认,发送方发送一段时间后没有收到确认就会重传。
- 数据校验:TCP报文头有校验和,用于校验报文是否损坏。
- 数据合理分片和排序:tcp会按最大传输单元(MTU)合理分片,接收方会缓存未按序到达的数据,重新排序后交给应用层。而UDP:IP数据报大于1500字节,大于MTU。这个时候发送方的IP层就需要分片,把数据报分成若干片,是的每一片都小于MTU。而接收方IP层则需要进行数据报的重组。由于UDP的特性,某一片数据丢失时,接收方便无法重组数据报,导致丢弃整个UDP数据报。
- 流量控制:当接收方来不及处理发送方的数据,能通过滑动窗口,提示发送方降低发送的速率,防止包丢失。
- 拥塞控制:当网络拥塞时,通过拥塞窗口,减少数据的发送,防止包丢失。
56.TCP和UDP的区别
-
连接性:TCP是面向连接的协议,它在通信双方之间建立可靠的连接,确保数据的准确交付和顺序。UDP是无连接的协议,它不建立连接,数据传输是无序的。TCP一对一,UDP可以多对多。
-
可靠性:TCP通过应用层帧(字节流)的切割和重组,使用可靠的机制(如确认、重传和拥塞控制)来确保数据的完整性和可靠性传输。UDP不提供任何可靠性机制,它仅仅是将数据报发送给目标地址,不负责确认和重传丢失的数据,UDP面向报文,需要应用层控制报文的大小。
-
传输方式:TCP 是流式传输,没有边界,但保证顺序和可靠。UDP 是一个包一个包的发送,是有边界的,但可能会丢包和乱序。
-
效率:由于TCP提供了对数据的可靠性保证,它会引入相应的开销,如确认和重传的机制,以及拥塞控制等。UDP没有这些机制,因此它的开销相对较低,传输效率更高。
-
适用场景:TCP适用于需要可靠性的应用,如文件传输、电子邮件和网页浏览等。UDP适用于实时性要求较高的应用,如音频/视频流传输、实时游戏和DNS查询等,因为它的传输速度相对更快。
57.TCP和UDP对应的应用层协议
TCP(文件,远控,邮件)
FTP:定义了文件传输协议,使用21端口.
Telnet:它是一种用于远程登陆的端口,23端口
SMTP:定义了简单邮件传送协议,服务器开放的是25号端口
POP3:它是和SMTP对应,POP3用于接收邮件。
UDP(DNS,网络管理,简单文件)
DNS:用于域名解析服务,用的是53号端口
SNMP:简单网络管理协议,使用161号端口
TFTP:简单文件传输协议,使用69号端口
58.数据链路层常见协议
协议 | 名称 | 作用 |
---|---|---|
ARP | 地址解析协议 | 根据IP地址获取物理地址 |
RARP | 反向地址转换协议 | 根据物理地址获取IP地址 |
PPP | 点对点协议 | 主要是用来通过拨号或专线方式建立点对点连接发送数据,使其成为各种主机、网桥和路由器之间简单连接的一种共通的解决方案 |
59.Ping命令基于什么协议
ping是基于网络层的ICMP协议实现的。
通过向对方发送一个ICMP回送请求报文,如果对方主机可达的话会收到该报文,并响应一个ICMP回送回答报文。
ICMP报文分为两个种类:
- ICMP差错报告报文,常见的有
- 终点不可达
- 时间超过
- 参数问题
- 改变路由
- ICMP询问报文
- 回送请求和回答:向特定主机发出回送请求报文,收到回送请求报文的主机响应回送回答报文。
- 时间戳请求和回答:询问对方当前的时间,返回的是一个32位的时间戳。
60.在进行UDP编程的时候,一次发送多少bytes好?
在普通的局域网环境下,将UDP的数据控制在1472字节以下为好
MTU为1500字节。这个1500字节就是网络层IP数据报的长度限制。
因为IP数据报的首部为20字节,所以IP数据报的数据区长度最大为1480字节。而这个1480字节就是用来放TCP传来的TCP报文段或UDP传来的UDP数据报的。又因为UDP数据报的首部8字节,所以UDP数据报的数据区最大长度为1472字节。
如果你发送的数据报大于MTU,它们可能会被IP层拆分成更小的分片,增加了丢失或重组的概率。因此,考虑到这些限制,确保你的数据报不会超过MTU大小。
61.RTO,RTT和超时重传分别是什么吗
超时重传:发送端发送报文后若长时间未收到确认的报文则需要重发该报文。
RTO:从上一次发送数据,因为长期没有收到ACK响应,到下一次重发之间的时间。
RTT:数据从发送到接收到对方响应之间的时间间隔,即数据报在网络中一个往返用时。
62.XSS攻击
跨站点脚本攻击,指攻击者通过篡改网页,嵌入恶意脚本程序,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式。
如何防范XSS攻击
1)前端,服务端,同时需要字符串输入的长度限制。
2)前端,服务端,同时需要对HTML转义处理。将其中的”<”,”>”等特殊字符进行转义编码。
防 XSS 的核心是必须对输入的数据做过滤处理。
63.CSRF攻击
跨站点请求伪造,指攻击者通过跨站请求,以合法的用户的身份进行非法操作。
可以这么理解CSRF攻击:攻击者盗用你的身份,以你的名义向第三方网站发送恶意请求。CRSF能做的事情包括利用你的身份发邮件,发短信,进行交易转账,甚至盗取账号信息。
64.文件上传漏洞是如何发生的
文件上传漏洞,指的是用户上传一个可执行的脚本文件,并通过此脚本文件获得了执行服务端命令的能力。
如何防范?
-
文件上传的目录设置为不可执行。
-
判断文件类型,只允许上传可靠类型。在判断文件类型的时候,可以结合使用MIME Type,后缀检查等方式。因为对于上传文件,不能简单地通过后缀名称来判断文件的类型,因为攻击者可以将可执行文件的后缀名称改为图片或其他后缀类型,诱导用户执行。
-
上传的文件需要进行重新命名,使攻击者无法猜想上传文件的访问路径,将极大地增加攻击成本,同时向shell.php.rar.ara这种文件,因为重命名而无法成功实施攻击。
-
限制上传文件的大小。
-
单独设置文件服务器的域名。
65.服务器出现大量close_wait的连接的原因是什么?
close_wait状态是在TCP四次挥手的时候收到FIN但是没有发送自己的FIN时出现的,出现大量close_wait状态的原因有两种:
- 服务器内部业务处理占用了过多时间,都没能处理完业务;或者还有数据需要发送;或者服务器的业务逻辑有问题,没有执行close()方法
- 服务器的父进程派生出子进程,子进程继承了socket,收到FIN的时候子进程处理但父进程没有处理该信号,导致socket的引用不为0无法回收
66.一台机器能够使用的端口号上限是多少,是否可以修改?
65536
因为TCP的报文头部中源端口号和目的端口号的长度是16位,也就是可以表示2^16=65536个不同端口号,因此TCP可供识别的端口号最多只有65536个。但是由于0到1023是知名服务端口,所以实际上还要少1024个端口号。
对于服务器来说,可以开的端口号与65536无关,其实是受限于Linux可以打开的文件数量,并且可以通过MaxUserPort来进行配置。
67.SELECT POLL EPOLL
select
代码实现
1.将需要监听的fd放到fd_set中
2.将设置好的fd_set放入select函数中监听,内核会无差别遍历每个fd判断是否有数据到达
3.对每个监听的fd查询在返回的fd_set中是否为1
POLL
代码实现
使用pollfd结构体数组fds存放需要监听的fd和对应的事件
将fds传入poll函数进行监听,内核会同样轮询每个fd查看监听事件是否发生
用户再遍历返回后的fds查看对应事件是否发生
EPOLL
代码实现
- 创建epoll红黑树
- 将需要监听的fd放到epoll_event数组中,每个fd对应一个epoll的节点
- 调用epoll_ctl 函数将每个节点上树
- epoll监听每个节点的事件,若监听事件发生,就将对应的节点放入就绪队列,再将就绪队列中的节点返回给用户