面试常问的计算机网络知识

OSI 与TCP/IP模型

image-20210622185441419

输入域名发生了什么

假设输入 www.baidu.com

浏览器解析域名。

客户端与服务端进行数据交互的时候,不能识别域名,通过DNS解析域名转化未对用的IP地址

  • 浏览器缓存中查找是否存在映射关系
  • 查询·本地host文件,查看是否存在域名与ip的对应关系,有的话则直接解析出来ip
  • host文件不存在,就去本地区的DNS服务器(移动联通电信运营商提供的dns)里面查找ip与域名是否有映射关系,有的话返回
  • 还没找到的话去根服务器查找
  • 根服务器会判断这个域名由谁管理,这里.com就由负责.com的顶级域名服务器管理,然后返回这个服务器的ip。顶级域名服务器(gTLD Server): .com、.cn等域名
  • 本地区的dns服务器会向这个顶级域名服务器的ip继续查询,他返回域名对应的域名服务器,这个域名服务器是你注册的域名服务器,这个域名的服务商的服务器将承担起域名解析的任务。
  • 域名服务器将解析出的ip返回给本地区的服务器
  • 本地区的服务器缓存解析结果
  • 将解析的结果返回给用户

image-20210706165143206

TCP/IP三次握手建立连接

引出一个问题:为什么是三次?两次建立连接存在什么问题?四次呢

  • 第一次握手,客户端的TCP向服务端的TCP发送连接请求报文,SYN=1(SYN代表发起一个新连接),和一个随机的起始信号seq=x(seq信号,32位,用于标识TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记)
  • 第二次握手,服务端TCP接收到请求报文之后,向客户机发送请求,并为该TCP连接分配TCP缓存和变量,他向客户端发送四个字段:SYN=1ACK=1(确认信号是有效的) 、ack=x+1(ack序号,32位,只有在ACK标志位置1时,ack才是有效的,ack=seq+1)、随机产生一个的一个seq=y
  • 客户机收到确认的报文时,需要继续向服务端确认,并且也要给该链接分配缓存和变量 ACK=1seq=x+1ack=y+1

几种状态的说明:

  • CLOSED:连接结束,没有任何连接状态
  • LISTEN:监听远端的连接,可以接收连接
  • SYN_SENT:客户端连接时,发送SYN之后进入SYN_SENT状态
  • SYN_REVD:服务端接收到了客户端发送的SYN报文
  • ESTABLISHED:标识已经成功建立TCP连接

image-20210706190622415

浏览器客户端向后端发送数据

  • 三次握手建立连接之后,向后台发送请求

后台返回数据给浏览器渲染

  • 解析html结构,构建dom树,那所有的标签解析出来

  • 构建cssom树,解析css样式

  • 执行script标签中的代码(所以避免将该标签放在头部,造成页面空白,形成阻塞 )

    • 普通标签:解析到script标签之后,加载脚本内容,然后执行,执行完毕之后继续解析html
    • defer:解析到script之后,不发生阻塞,一边解析html,一遍加载脚本,等带html解析全部解析完成之后,在执行脚本
    • async:与defer相似,只是脚本执行的时机不同,他在加载脚本时不发生阻塞,等待叫脚本加载完成之后,执行脚本

    image-20210706180850976

  • 将dom和cssom合并成渲染树

  • 根据渲染树将页面绘制出来

四次挥手断开连接

引出一个问题:三次挥手行不行

  • 第一次挥手,客户端发送一个连接释放报文,并停止再发送数据,主动关闭TCP连接, FIN=1(释放一个连接),seq=u
  • 第二次挥手: 服务器接收连接释放报文后即发出确认, ACK=1ack=u+1seq=v此时, 从客户机到服务器这个方向的连接就释放了, TCP连接处于半关闭状态. 但服务器若发送数据, 客户机仍要接收, 即从服务器到客户机的连接仍未关闭.
  • 第三次挥手: 若服务器已经没有了要向客户机发送的数据, 就通知TCP释放连接, 此时其发出FIN=1的连接释放报文FIN=1ACK=1seq=wack=u+1
  • 第四步: 客户机收到连接释放报文后, 必须发出确认. 在确认报文中, ACK字段被置为1, 确认号ack=w+1, 序号seq=u+1. 此时, TCP连接还没有释放掉, 必须经过等待计时器设置的时间2MSL(MSL:报文的最大生存时间)后, 客户端才进入到连接关闭状态.

几种状态得说明:

  • FIN_WAIT_1客户端发送FIN=1得关闭连接得的请求之后进入该状态

  • CLOSE_WAIT :服务端收到客户端发送得关闭连接的请求后,确认信号是有效的,回应客户端之后进入

  • FIN_WAIT_2:客户端收到服务端响应的ACK之后进入。进入半关闭的状态,只能客户端只能接受数据,不能发送数据

  • LAST_ACK:服务端发送一个FIN关闭信号给客户端,等待对方确认

  • TIME_WAIT:客户端接收到服务端发送的FIN关闭信号之后进入,等待足够的时间2MSL,以此确保客户端收到确认关闭连接的ACK

  • CLOSED:连接结束

image-20210706194555501

TCP与UDP协议

  • UDP协议:UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。
  • TCP协议:TCP协议全称是传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。T
UDP TCP
是否连接 无连接,不用关心对方是否接收到 面向连接,需要确保双方建立正确的连接
是否可靠 不可靠传输,不使用流量控制和拥塞控制 可靠传输,使用流量控制和拥塞控制
连接对象个数 支持一对一,一对多,多对一和多对多交互通信 只能是一对一通信
首部开销 首部开销小,仅8字节 首部最小20字节,最大60字节
适用场景 适用于实时应用(IP电话、视频会议、直播等),速度要求快 适用于要求可靠传输的应用,例如文件传输

HTTP

无状态的,以请求/应答方式运行的协议,她使用可拓展的语义和自描述消息格式,与基于网络的超文本信息系统(html页面)灵活的互动

  • 无状态的:不会去存储用户的信息
  • 请求/应答:发送请求===>得到相应
  • 可拓展:在协议的基础可以对请求头部添加一些字段
  • 自描述:可以传输文本、图片等格式

请求类型

  • get:参数挂载在url上,只被用于获取数据

  • post:将实体提交到指定的资源,侧重于新增数据

  • put:侧重于修改数据 ,整体更新

  • patch:对put方法的额外补充,用于局部更新

  • delete:删除指定资源

  • head:与get相同,但是只返回响应头,没有响应主体

  • options:预检请求,检查服务器支持哪些http方法,响应体中包含一个Allow字段,包含了所支持的方法

    image-20210707143019115

  • connect:创建一个客户端与请求资源之间双向通信的隧道,点对点通信

  • trace:服务端原样返回接收到的信息,提供了一种用于debug方法

RESTful请求风格

参考阮一峰大佬的REStful API设计指南

RESTful是面向资源请求,url中不能存在动词,只能有名词。

https://api.example.com/v1/zoos

对于具体资源的操作,HTTP提供了上面的请求类型,可以使用这些动词来表对资源进行哪些操作,对于一些参数,比如:获取Tom的数学成绩,用get请求来写的话,请求地址就是/tom?subject=math,但是用RESTful风格来写就是/tom/math,列出一些常用例子:

//方法  	接口   				行为
GET 	/zoos:				列出所有动物园
POST 	/zoos:				 新建一个动物园
GET 	/zoos/ID:			 获取某个指定动物园的信息
PUT 	/zoos/ID:			 更新某个指定动物园的信息(提供该动物园的全部信息)
PATCH 	/zoos/ID:			 更新某个指定动物园的信息(提供该动物园的部分信息)
DELETE 	/zoos/ID:			 删除某个动物园
GET 	/zoos/ID/animals:	  列出某个指定动物园的所有动物
DELETE 	/zoos/ID/animals/ID:  删除某个指定动物园的指定动物

axios里面同样提供了这些请求方法的别名

axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])

请求头

  • Accept 浏览器可接受的数据格式

  • Accept-Encoding 浏览器可接收的压缩算法,如 gzip

  • Accept-lanuage 浏览器能接收的语言

  • Connection: keep-alive 一次TCP连接重复使用(一次连接,多次使用)

  • cookie 非跨域请求都会带上

  • Host请求的域名

  • User-Agent(简称 UA)发出请求的客户端,浏览器信息

  • Content-type 发送方数据的格式,如application/json

    • application/json :转化成json字符串形式
    • multipart/form-data: post 传输文件
    • application/x-www-form-urlencoded :form表单默认格式,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字符串(name1=value1&name2=value2)然后把这个字串append到url后面,用?分割,加载这个新的url。 当action为post时候,浏览器把form数据封装到http body中,然后发送到server。

image-20210707174138041

HTTPS

  • 在HTTP协议通信的基础上,使用SSL/TLS为网络通信提供安全及数据完整性的一种安全协议,对网络连接进行加密

WebSocket

参考WebSocket相关知识

跨域问题

原因

  • 同源策略:协议,域名,端口号都相同的话,则称之为同源,为了保证用于信息的安全,不同源的情况下,下面的行为会受到限制:
    • cookie,localStorage,indexDB无法读取
    • 无法获取DOM
    • 请求的响应被浏览器拦截

解决方案

jsonp

imglinkscript标签不受同源策略的影响。jsonp本质是动态创建script标签,利用他不产生跨域的特点,向后台发送请求

  • 前端先声明一个请求成功之后的回调函数 sayName`
  • 前端创建script标签,后台接收到请求之后,通过一些处理返回一个函数名,并且把数据当作参数放进去,返回sayName('Tom')
  • 请求成功之后数据会被放进去,执行sayName

script加载资源发送的请求是get请求,以至于jsonp也有这个局限。

node中间件代理

同源策略仅仅是浏览器的限制,对于服务器之间的相互请求则不做限制

image-20210712152512784

例如这里,前端需要向localhost:5000请求数据。项目npm run dev运行的时候,在本地启动了一个服务4000,前端发送请求的时候会经由4000,然后他再向5000发送请求,4000向5000转发请求不涉及跨域,请求成功之后,5000给4000返回响应,然后4000再转发给前端

  • 使用vue开发项目时,不可避免的要遇到跨域问题,通常去配置脚手架中的proxyTable(根据脚手架版本),这里就是利用了中间件,本地启动一个服务,所有的请求都发送到本地创建的服务,然后由他转发给后台

image-20210712150046974

  • react跨域问题同样用也可以用这个方法解决

image-20210423183253583

CORS

跨域资源共享,关键实现在于服务端。

image-20210712160625485

  • Access-COntrol-Allow-Origin:关键属性,要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
  • Access-Control-Allow-Credentials:默认为false,表明请求是否携带credentials(代表cookies, authorization headers 或 TLS client certificates),Credentials必须在前后端都被配置(即后台Access-Control-Allow-Credentials 和 前端XHR 或Fetch request中都要配置)才能使带credentials的CORS请求成功。如果决定要发送cookie,那么Access-Control-Allow-Origin属性不能设置成*,必须指定必须的,于请求一致的域名origin
  • Access-Control-Expose-Headers:出现在响应头中,暴露出来的响应头,供XMLHttpRequest对象的getResponseHeader()获取额外的头部信息
  • Access-Control-Allow-Methods:出现在预检请求的响应中,表明服务端支持跨域的方法
  • Access-Control-Allow-Headers:出现在预检请求的响应中,表示服务端支持的所有头部信息,如果请求头设置了Access-Control-request-Header,那么该字段必需。
  • Access-Control-Max-Age:出现在预检请求的响应头中,表示预检请求的有效期,单位秒,在这个时间内不在发送预检请求
  • Access-Control-Request-Method:必选,出现在预检请求的请求头中,表示真正请求实会采用那种请求方法
  • Access-Control-Request-Header:出现在预检请求的请求头中,表示服务器在真正的请求中会采用哪些请求头

Nginx反向代理

正反向代理

配置nginx的nginx.conf文件

浏览器访问 http://localhost:81时,转发到 https://mywebsite.com

server {
    	#访问的端口号
        listen       81;
        #访问的地址
        server_name  localhost; 
        location / {
            root   html;
            index  index.html index.htm;
        #转发的地址
            proxy_pass https://mywebsite.com;
        }
}

HTTP缓存

参考一文读懂http缓存

向服务器请求数据时,会又优先查询浏览器缓存,如果缓存中存在需要请求的数据,就直接从浏览器缓存中提取出来数据,常见的http缓存只能缓存get请求响应的资源

  • http缓存分类:根据是否重新向服务器发起请求来分类,可分为强缓存协商缓存

  • http缓存过程:

    • 第一步:浏览器第一次请求数据,服务端返回资源,在响应头中添加资源的缓存参数。
    • 第二步:判断请求的数据,查看是否命中强缓存,如果命中,则返回状态码200,从浏览器获取资源,请求不会被发送到服务端
    • 第三步:未命中强缓存,则向服务器发送请求,服务器会对 比缓存是否失效了,是否更新了,如果资源更新了则返回状态码200,从服务器获取资源,并且更新缓存,如果判断发现未更新,则返回状态码304,然后去浏览器中获取资源

强制缓存

强制缓存在缓存未过期的情况下,即Cache-Control的max-age属性或者Expires未过期,那么就会去返回浏览器的缓存,强制缓存生效时,http状态码是200,这种方式是页面加载速度最快的,因为他没有与服务器进行交互。但是假如在服务器的资源被修改了,这时候拿到的缓存就不是我们预期的数据了,页面上刷新了但没有生效,因为走的是强制缓存,所以Ctrl + F5一顿操作之后就好了。 跟强制缓存相关的header头属性有(Pragma/Cache-Control/Expires)

相关属性:

  • Cache-Control
    • no-store:禁止任何缓存策策略,请求时服务器都要响应一个新的资源
    • no-cache不使用强缓存,直接去使用协商缓存,与no-cache互斥,同时设置时,以`no-store为准
    • max-age:代表一个相对的时间长度,相对于客户端时间,单位是秒,例如Cache-Control:max-age=31536000,意味着在成功请求的31536000秒后过期,每次请求成功会延迟失效时间
    • s-maxage:代理服务器缓存有效时间,public情况下有效
    • private:默认值,只能被浏览器缓存
    • public:可以被浏览器缓存,也可以被代理服务器缓存,
  • Expires设置一个固定的时间,在这个时刻缓存过期,Expires:Mon, 20 Jul 2017 10:08:35 GMT ,在这个时刻之前都是有效的,请求成功不会延时失效时间,一般情况下都是使用Cache-Control

image-20210708104444973

协商缓存

响应头中没有Cache-Control和Expires或者Cache-Control和Expires过期还或者它的属性设置为no-cache时(即不走强缓存),那么浏览器第二次请求时就会与服务器进行协商(通过判断last-modified/if-modified-since是否一致或者Etag/If-None-Match是否一致),与服务器端对比判断资源是否进行了修改更新。服务端资源没有更改,则返回304.然后从浏览器获取资源,已更改则从服务器获取资源,返回200

实现协商缓存的两种方式:

  • Last-modified:存在于响应头中,标识文件的最后修改时间
  • If-modified-Since:存在于请求头里面,值为之前返回的last-modified

上面一组属性可以解决大部分缓存情况,但是存在一些不足,他们的时间戳单位是秒,也就是说,如果发生修改资源的太快,在击几百毫秒之内完成,对于他们来说仍是相等的,无法识别出资源已经更新。另外也可能存在只改变文件名而不改变文件内容的情况,这种情况会被认定为资源更新,会去服务请资源而耗费性能。对于着二者的缺点,可以使用 Etag/If-None-Match的方案优化

  • Etag:存在于文件的哈希值,唯一的,资源改变会改变它的Etag
  • If-None-Match:存在于请求头,值为之前返回的Etag

比较上面两种协商缓存的方案,他们都有一个共同流程,首次请求服务端返回一个标识放在响应头中,第二次及以后的请求都会将响应头的这个值放在请求头中,通过比较两个值来判断资源是否更改

这种方案并不能完全替代last-modified,他只能作为一种补充,因为它同样存在一些不足,首先,文件的哈希值需要服务器去计算,对服务器造成了额外的开销,尤其对于一些大文件或者文件数目很多的情况,频繁计算文件哈希值造成了性能的而损耗。另外,生成etag的过程中存在精度问题,某些情况会造成比对失败

总结

  • 缓存决策过程:

image-20210708154624127

  • 不同类型的文件缓存方案:

    具体的缓存方案需要根据实际的开发场景来决定

    • html文件需要及时的更新,需要设置成协商缓存
    • 图片文件等媒体文件较大,可能会定期的替换更改,可以设置较短时间的强制缓存
    • css样式文件,js脚本文件可以可以设置较长时间的强缓存
  • 刷新页面的行为

    • F5 刷新页面 仍然会去查找浏览器种的强缓存然后去找协商缓存
    • Ctrl+F5 强制刷新 Cache-Control会变成·no-chche即不走强缓存

浏览器存储方案

cookie、localStorage、sessionStorage的使用

安全

XSS

跨站脚本攻击,向客户端插入脚本,用户打开网页或者点击某个按钮会运行注入的脚本

参考于美团技术团队: 如何防止XSS攻击

注入的情景

  • 在 HTML 中内嵌的文本中,恶意内容以 script 标签形成注入。渲染文本时,后台返回的数据包含script标签
<h1>前端渲染后台返回的数据: <script>alert(1)</script> </h1>
  • 在内联的 JavaScript 中,拼接的数据突破了原本的限制(字符串,变量,方法名等)。
  <script>
      let backendData = alert(1) //后端的数据
      let data = backendData //前端对这些数据进行操作
      console.log(data)
    </script>
  • 在标签属性中,恶意内容包含引号,从而突破属性值的限制,注入其他属性或者标签。
后台返回的数据   "><script>alert('XSS');</script>
<input type="text" value="<%= getParameter("keyword") %>">
拼接后:
<input type="text" value=""><script>alert('XSS');</script>">
  • 在标签的 href、src 等属性中,包含 javascript: 等可执行代码。
后台返回的数据:javascript:alert('XSS')
<a href="<%= escapeHTML(getParameter("redirect_to")) %>">跳转...</a>
拼接后
<a href="javascript:alert('XSS')">跳转...</a>
  • 在 onload、onerror、onclick 等事件中,注入不受控制代码。
  • 在 style 属性和标签中,包含类似 background-image:url("javascript:..."); 的代码(新版本浏览器已经可以防范)。
  • 在 style 属性和标签中,包含类似 expression(...) 的 CSS 表达式代码(新版本浏览器已经可以防范)。

XSS分类

根据攻击的来源,XSS 攻击可分为存储型、反射型和 DOM 型三种。对于前两种,后端应该做好防护,而第三种DOM型需要前端防范

  • 存储型:提交恶意代码到数据库中,用户打开页面时,从后台取出这些数据,然后拼接数据,浏览器渲染页面的时候会执行这些代码,常见于评论,私信,发布文章等场景
  • 反射型:构造出特殊的URL,用户点击跳转这个URL时,恶意代码也被解析执行。常见于通过 URL 传递参数的功能,如网站搜索、跳转等。与存储型不同的是:存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里
  • DOM型:攻击者构造出特殊的 URL,用户打开带有恶意代码的 URL,恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作

如何防范

对于存储型和反射性

他们都是从后台取出恶意代码,然后再html中被拼接,被浏览器执行,有两种方法预防:

  • 改成纯前端渲染,把代码和数据分隔开。这在很多内部、管理系统中常用

    1. 浏览器先加载一个静态 HTML,此 HTML 中不包含任何跟业务相关的数据。
    2. 然后浏览器执行 HTML 中的 JavaScript。
    3. JavaScript 通过 Ajax 加载业务数据,调用 DOM API 更新到页面上。明确的告诉浏览器:下面要设置的内容是文本(.innerText),还是属性(.setAttribute),还是样式(.style)等等。浏览器不会被轻易的被欺骗,执行预期外的代码了
  • 对 HTML 做充分转义。采用合适的转义库,如 doT.js、ejs、FreeMarker 等,对 HTML 模板各处插入点进行充分的转义。把一些关键字符力例如& < > " ' /等转义掉,HTML 的编码是十分复杂的,在不同的上下文里要使用相应的转义规则

对于DOM型

  • DOM型是因为页面把不可信的数据当成了代码执行,所以在使用 .innerHTML.outerHTMLdocument.write() 时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用 .textContent.setAttribute() 等,对于Vue/React 技术栈,尽量不使用 v-html/dangerouslySetInnerHTML 功能,在前端 render 阶段避免 innerHTMLouterHTML 的 XSS 隐患。DOM 中的内联事件监听器,如 locationonclickonerroronloadonmouseover 等,<a> 标签的 href 属性,JavaScript 的 eval()setTimeout()setInterval() 等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,

其他防范措施

  • 对要提交的输入内容做长度限制
  • 对cookie设置http-only属性,禁止前端浏览器读取cookie
  • 验证码:防止脚本冒充用户提交危险操作

CSRF

参考美团技术团队 如何防止CSRF攻击

跨站请求伪造,引导用户进入第三方网站中,然后发送请求,冒充用户身份,对被攻击的网站执行某些操作,

常见攻击类型

  • GET请求类型,进入第三方网站后,浏览器请求图片资源,然后发送向被攻击网站发送请求
//从 bank.example 中拿到用户cookie
<img  style="0;" src="http://bank.example/withdraw?amount=10000&for=hacker" > 
  • POST请求,进入第三发放网站自动提交表单发送一个post请求
<form method="POST" action="https://bank.example/xxx" enctype="multipart/form-data"> 
    <input type="hidden" name="name" value="xiaoming"/> 
    <input type="hidden" name="amount" value="10000"/>
</form> 
<script> 
    document.forms[0].submit();
</script>
  • 跳转连接,诱导用户点击页面中的链接,在连接中伪造请求
<a href="http://bank.example/withdraw?amount=10000&for=hacker" taget="_blank">重磅消息!! <a/>

如何防范

CSRF只是冒用cookie,并不能获取到cookie的实际值,另外,CSRF通常发生在第三方网站

同源检测

  • Origin(只有协议、域名、端口号。不包含路径的详细信息) 或者Referer(协议、域名、端口号、参数。页面来源的详细地址)。包含了请求的来源信息,可以判断请求的来源,禁排除掉外域(或者不受信任的域名)的请求操作

SameSite属性

SamesiteCookie是一个可能替代同源验证的方案,但目前还并不成熟,其应用场景有待观望。

  • SameSite=None不做限制,浏览器会在同站请求、跨站请求下继续发送 cookies
  • SameSite=Strict:只在访问相同站点时发送 cookie
  • SameSite=Lax:假如这个请求是这种请求(改变了当前页面或者打开了新页面)且同时是个GET请求,则这个Cookie可以作为第三方Cookie

JWT验证

  • 后端根据用户生成一个Token,然后把Token返回给前端,前端保存Token
  • 调用其他接口进行交互时,新增一个请求头字段,放Token
  • 后台接收到Token时比验证Token是否一致

其他防范措施

  • get请求不要包含增改删功能,仅查询数据
  • 对于用户来说,尽量避免打开可疑链接,或者用不常用的浏览器打开

攻击者诱导受害者进入第三方网站,再第三方的网站中,向被攻击的网站发送请求,由于再第三方网站中,用户存在cookie,已经完成身份验证,所以在

Fetch

参考文档 :使用Fetch

Fetch作为一种Http请求方案,是XHR的代替方案,注意Fetch是基于Promise原生的API,而Axios是基于Promise的库,Fetch使用方法与Axios十分类似,注意post请求时,fetch传递的时body属性,值是对象转化成字符串JSON.stringify(data)

拓展

TCP三次握手连接的原因

首先要知道TCP三次握手的目的是什么:为了确保双方的发送和接收能力都是正常且可靠的

  • 不能采用两次握手的原因:结合三次握手的流程图来看,去掉第二次握手----服务端向客户端的响应的话,客户端不能确认服务端是否具有正常的发送功能,额外举个例子:客户端显示发送了一个连接请求,但是由于某些原因导致他一致在传输的路上,没有被客户端收到。这个时候客户端会认为这个请求是不是发送出错了,然后又给客户端发送了一条连接请求,然后巧了,客户端收到了这个请求,双方于是建立了连接,传输了数据,然后断开了连。然而这个时候客户端发送的第一条连接请求终于到了,服务端收到了,于是又建立了连接,造成服务端资源的浪费
  • 不采取四次握手的原因:三次握手完全足够双方确认是否能够正常收发信息,不需要额外的握手交互了

TC四次挥手的原因

  • 客户端在发送断开连接的请求·FIN之后,服务端并不能及时的响应断开连接的请求FIN,必须等到服务端所有的报文都发送完毕,这个过程需要一定时间。去除第二次服务端给客户端的回应的话,期间等待服务端发送完毕的过程中,长时间没回应的话,客户端会认为丢包,然后又给服务端发了一个FIN关闭请求,这时就会出现问题。

正向代理与反向代理

正向代理是客户端和其他所有服务器(重点:所有)的代理者,而反向代理是客户端和反向代理服务器所代理的服务器之间的代理(也就是说反向代理有可能代理2个服务器,3个服务器等)

  • 正向代理:多个用户代理服务器发送请求,然后转发给一个目标服务器,比如 FQ提子
  • 反向代理:一个用户代理服务器发送请求,然后代理服务器推断请求,发送到多个服务器中的一个
原文地址:https://www.cnblogs.com/baifangzi/p/15015938.html