程序员的日常大戏”又来了。
事情是这样的一位后端兄弟刚入职国企,写了几个接口,用了put和delete,结果前端同事却跳出来说:“兄弟,这俩不能用,改成post吧!
不过人家前端同事是真的在找茬吗?
其实人家真不是故意找事儿,确实在前端开发中很少使用put和delete接口。
为什么我们在和后端对接的时候,很少用PUT和DELETE接口,而是更多地使用POST和GET接口。
首先,我得先和大家解释一下什么是HTTP请求方法。
HTTP请求方法有很多种,常见的有GET、POST、PUT、DELETE、PATCH等。这些方法其实就像我们平常在快递公司寄包裹时选择的服务类型:快递、普通包裹、EMS等等,每种服务类型都有自己的用途和特点。
GET方法主要用于向服务器请求数据。比如,你想查看某个网页内容,浏览器就会发起一个GET请求,把你请求的内容下载到本地展示出来。
GET请求的特点是“只读”,不对服务器上的资源产生任何影响。这就像我们去图书馆查资料,只是在那儿读书,不带走也不更改任何书籍内容。
POST方法则用于向服务器提交数据。假如我们需要在网站上填写一个表单,比如注册账户、提交订单等,就需要用到POST请求。POST请求的特点是“可写”,可以在服务器上创建新的资源或对现有资源进行修改。
就好比我们去邮局寄信,把信件交给邮局,邮局会根据信件内容进行处理和投递。
既然GET和POST这么常用,那PUT和DELETE是干嘛的呢?
PUT方法用于更新资源,而DELETE方法则用于删除资源。听起来也很有用,为什么在前端开发中很少用到它们呢?
PUT方法可以说是“更新大王”。当我们需要更新服务器上的资源时,比如修改用户信息、更新文章内容等,就需要用到PUT请求。
然而,PUT请求有个特点:它通常要求客户端发送完整的资源信息。举个例子,如果我们需要更新用户的邮箱地址,可能需要把整个用户信息(包括用户名、密码、地址等)都发送给服务器。
这样做虽然看起来很规范,但在实际开发中并不总是方便。
首先,前端开发需要额外处理更多的数据,这无形中增加了代码的复杂性和工作量。
其次,PUT请求通常被认为是幂等的,意思是无论你发送多少次同样的请求,服务器的资源状态应该是一样的。这对于一些需要部分更新的操作来说,未免有些不太灵活。
DELETE方法则用于删除服务器上的资源。比如,你要删除一个账户、移除一篇文章,就可以使用DELETE请求。但是DELETE请求也有它的问题。
首先,DELETE请求不安全。很多浏览器和防火墙会对DELETE请求进行严格限制,防止恶意用户通过发送DELETE请求删除不该删除的数据。这就导致我们在前端开发中使用DELETE请求时,往往会遇到种种限制和麻烦。
其次,DELETE请求的可追溯性差。DELETE请求一旦成功,资源就被彻底删除了,这样一来,如果出问题了,很难追溯删除的原因和时间。这对于一些需要审计和数据恢复的场景来说,DELETE请求显然不是最好的选择。
其实我之前在前端开发中也遇到过这种情况。记得有一次,我们团队在开发一个电商平台时,遇到了一个关于接口调用的问题。当时我们需要实现商品信息的更新和删除功能,后端同事建议我们使用PUT和DELETE请求。
然而在实际开发中,我们发现PUT和DELETE请求在一些浏览器中会遇到兼容性问题,导致功能无法正常使用。
于是,我们决定改用POST请求来实现这些操作。
在POST请求中,我们通过增加一个操作类型的参数,来区分是更新还是删除操作。这样一来,不仅解决了兼容性问题,还简化了前端代码的实现。
所以选择合适的HTTP请求方法,不仅可以提高开发效率,还能保证应用的稳定性和兼容性。
HTTP请求方法有很多种,每种方法都有其特定的用途和特点。
在前端开发中,GET和POST请求因为其简单易用、兼容性好、安全性高等优点,成为了我们最常用的请求方法。
而PUT和DELETE请求虽然也很有用,但由于其复杂性和兼容性问题,在实际开发中相对少用。
最后,希望大家在今后的开发中,能够灵活运用这些知识,打造出更加优秀和稳定的应用。
文公众号来源:01二进制 作者:雇个城管打天下
记得在面试的时候也被问到这题,当时答得并不好,这道题目其实可以挖掘很多的知识点出来,建议阅读!
前几天有个学妹问我为什么在浏览器里面输了网址就会显示出来页面,虽然这个现象很常见,但是要想解释清楚确实有些小困难,当时也只是简单的回答了她,现在想趁着这个机会好好整理下相关知识。整理完才觉得其实就和我们去一个地方找人是一个道理。所以说艺术源于生活却又高于生活,技术同样如此。
在回答这个问题前, 我们先来了解下我们平常说的那个网址到底是啥?
网址的学名叫做统一资源定位符(Uniform Resource Locator, 常缩写为URL), 我们知道现在的互联网其实就是由众多资源所构成的一张巨大的网, 如何定位那些资源就是靠的URL, 因此我们也可以把URL理解为是网络上资源的“门牌号“, 我们在浏览器中输入网址, 就相当于开一辆车(浏览器)去找一个地址(URL)
1. 缓存查找
如果你要出门找一个地方, 第一想法肯定是先想这个地方你有没有去过, 你要是去过的话那就不需要问人直接过去就好了。 我们的系统也是这么想的。 当你在浏览器中输入了URL之后, 浏览器会先查看 浏览器缓存 中有没有这个地址, 如果没有那就再去 系统缓存, 如果系统缓存还没有, 那就去路由器缓存找, 总之只要缓存中有, 就说明有这个资源, 那浏览器直接显示出来就好了。
Tips: 这里说下 hosts文件 , hosts 是一个没有扩展名的系统文件, 可以用记事本等工具打开, 其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”, 当用户在浏览器中输入一个需要登录的网址时, 系统会首先自动从 hosts 文件中寻找对应的 IP 地址,一旦找到, 系统会立即打开对应网页, 如果没有找到, 则系统会再将网址提交 DNS 域名解析服务器进行IP地址的解析。 需要注意的是, hosts文件配置的映射是静态的, 如果网络上的计算机更改了请及时更新IP地址, 否则将不能访问。
2. DNS 解析
如果你认得去那个地址的路自然是最好, 那如果你根本就没去过那咋办? 肯定会有人说导航, 但并不是所有的地方都是导航能搜到的, 这个时候我们自然而然就会想着去问路人了。 浏览器也是这样的, 如果在本地缓存中没有找到想要的资源, 那就只能去其他网络上的机器中寻找我想要的资源了。 那你怎么知道你要的资源在那台机器上? 这时, DNS就横空出世了。
DNS(Domain Name System, 域名系统),DNS解析的过程就是寻找哪台机器上有你需要资源的过程。当你在浏览器中输入一个地址时, 例如 www.baidu.com, 其实这段URL并不是真正意义上的地址。 互联网上每一台计算机的唯一标识是它的 IP 地址(比如127.0.0.1就是我们本机的 IP 地址), 但是 IP 地址并不方便记忆(毕竟都是很长的数字串), 所以也就出现了网址(URL)这个玩意了, 目的就是为了方便普通用户去寻找网络上的其他计算机。 所以 DNS 实际上充当了一个翻译的角色, 将网址翻译成 IP 地址(就跟我想去南京大学, 问路的那个人告诉我南京大学在广州路上是一个道理)。
2.1 DNS 解析过程
DNS解析其实是一个递归查询的过程:
在上述过程中, 首先在本地域名服务器中查询 IP 地址, 如果没有找到, 本地域名服务器会向根域名服务器发送一个请求, 如果根域名服务器也不存在该域名时, 本地域名会向com顶级域名服务器发送一个请求, 依次类推下去。 直到最后找到目标网址所对应的 IP, 并将其缓存到本地, 以供下次使用。
2.2 DNS负载均衡
在讲DNS负载均衡前先来看张图片:
看到这可能就会有人犯嘀咕了, 我们不是 ping 的同一个网址吗, 为啥两次IP都不一样啊? 其实原因很简单, 如果每次都一样是否说明你请求的资源都位于同一台机器上面, 那么这台机器需要多高的性能和储存才能满足亿万请求呢? 其实真实的互联网世界背后存在成千上百台服务器, 大型的网站甚至更多。 但是在用户的眼中, 它需要的只是处理他的请求, 哪台机器处理请求并不重要。 DNS可以返回一个合适的机器的IP给用户, 例如可以根据每台机器的负载量, 该机器离用户地理位置的距离等等, 这种过程就是DNS负载均衡, 又叫做DNS重定向。
再来举个例子, 如果你在新街口用地图搜南京大学, 返回给你的第一条数据可能就是南京大学鼓楼校区(因为距离最近), 但如果你是在仙林用地图搜南京大学, 返回给你的第一条数据就有可能是南京大学仙林校区了。 DNS负载均衡简单来说也是这个道理。
2.3 DNS 污染
DNS 污染(DNS cache pollution), 又称域名服务器缓存投毒(DNS cache poisoning), 是指一些刻意制造或无意中制造出来的域名服务器数据包, 把域名指往不正确的IP地址。
某些网络运营商为了某些目的, 对DNS进行了某些操作, 导致上网的用户无法通过域名取得正确的IP地址。 某些国家或地区出于某些目的为了防止某网站被访问, 而且其又掌握部分国际DNS根目录服务器或镜像, 也会利用此方法进行屏蔽。 (Google、 Facebook等)
至于如果防止DNS污染, 这里只说一个方法就是修改hosts文件, 其他的自行搜索吧。
3. TCP连接
其实在上面DNS解析的图中就已经有了TCP连接的过程了:
我们通过DNS解析获取到了网址所对应的IP地址后, 便需要发起TCP连接请求, 这里总共需要三次握手, 具体的过程就不赘述了, 可以查阅相关资料, 这里推荐刘欣老师的《TCP/IP 之 大明王朝邮差》, 以及大学计算机网络课本里面的TCP相关章节。
4. HTTP 请求
握手成功后, 浏览器就可以向服务器发送http请求了, 请求数据包。 发送HTTP请求的过程就是构建HTTP请求报文并通过TCP协议中发送到服务器指定端口(HTTP协议80/8080, HTTPS协议443)。HTTP请求报文是由三部分组成: 请求行,请求报头和请求正文。
4.1 请求行
格式如下:
Method RequestURL HTTPVersion CRLF
例如:
GET index . html HTTP / 1.1
常用的方法有: GET,POST,PUT,DELETE,OPTIONS,HEAD。
4.2 请求报头
请求报头允许客户端向服务器传递请求的附加信息和客户端自身的信息。
Tips:客户端不一定特指浏览器, 有时候也可使用Linux下的CURL命令以及HTTP客户端测试工具等。
常见的请求报头有: Accept,AcceptCharset,AcceptEncoding,AcceptLanguage,ContentType,Authorization,Cookie,UserAgent等。
上图是使用Chrome开发者工具截取的对百度的HTTP请求以及响应报文, 从图中可以看出, 请求报头中使用了Accept, AcceptEncoding, AcceptLanguage, CacheControl, Connection, Cookie等字段。 Accept 用于指定客户端用于接受哪些类型的信息, AcceptEncoding 与 Accept 类似, 它用于指定接受的编码方式。Connection 设置为 Keepalive 用于告诉客户端本次 HTTP 请求结束之后并不需要关闭 TCP 连接, 这样可以使下次 HTTP 请求使用相同的 TCP 通道, 节省 TCP 连接建立的时间。
5. 服务器响应
这部分对应的就是后端工程师眼中的 HTTP。 后端从在固定的端口接收到 TCP 报文开始, 这一部分对应于编程语言中的 socket。 它会对 TCP 连接进行处理, 对 HTTP 协议进行解析, 并按照报文格式进一步封装成 HTTP Request对象, 供上层使用。 这一部分工作一般是由 Web 服务器去进行, 常用的Web服务器有 Tomcat, IIS 和 Netty 等等。
HTTP响应报文也是由三部分组成: 状态码, 响应报头和响应报文。 篇幅原因这里就不详细展开了。
6. 浏览器解析网页信息
服务器返回给浏览器的文本信息, 通常是 HTML, CSS, JS, 图片等文件, 那么浏览器是如何对泽泻内容进行渲染呢? 通常是下面五个步骤:
不过这五个步骤在不同内核的浏览器中执行细节是不同的, 想深入了解的可以查阅相关资料, 这里推荐一篇文章:《浏览器渲染页面过程与页面优化》(https://segmentfault.com/a/1190000010298038)
浏览器是一个边解析边渲染的过程。 首先浏览器解析HTML文件构建DOM树, 然后解析CSS文件构建渲染树, 等到渲染树构建完成后, 浏览器开始布局渲染树并将其绘制到屏幕上。
JS的解析是由浏览器中的 JS 解析引擎完成的。 JS是单线程运行, 也就是说, 在同一个时间内只能做一件事, 所有的任务都需要排队, 前一个任务结束, 后一个任务才能开始。 但是又存在某些任务比较耗时, 如IO读写等, 所以需要一种机制可以先执行排在后面的任务, 这就是: 同步任务(synchronous)和异步任务(asynchronous)。 JS的执行机制就可以看做是一个主线程加上一个任务队列(task queue)。 同步任务就是放在主线程上执行的任务, 异步任务是放在任务队列中的任务。 所有的同步任务在主线程上执行, 形成一个执行栈; 异步任务有了运行结果就会在任务队列中放置一个事件; 脚本运行时先依次运行执行栈, 然后会从任务队列里提取事件, 运行任务队列中的任务, 这个过程是不断重复的, 所以又叫做事件循环(Event loop)。 如下图所示:
7. 总结
当上述步骤执行完成后我们便可在浏览器中看到一个完整的页面了, 总结下其实就只有几步:
其实简单来看这几个过程并不是很复杂, 但是每个步骤都可以深挖出一大堆的知识, 比如DNS的优化、页面渲染的优化、 HTTPS等等非常多的东西, 这里考虑到篇幅以及科普效果很多东西都一笔带过了。
微信公众号【程序员乔戈里】 作者乔戈里,斜杠青年,哈工大本硕985 硕士,百度Java 研发工程师,目前致力于分享求职必备学习经验、求职心得和成长感悟/技术文章。(关注公众号送9000G 考研/python/C++/java/前端/小程序/微信公众号/机器学习/人工智能资源)
者 | MageByte团队
来源 | 码哥字节(ID:MageByte)
头图 | CSDN 下载自东方IC
详解输入网址点击回车,后台到底发生了什么。透析 HTTP 协议与 TCP 连接之间的千丝万缕的关系。掌握为何是三次握手四次挥手?time_wait 存在的意义是什么?全面图解重点问题,再也不用担心面试问这个问题。
大致流程
URL 解析,解析 http 协议、端口、资源地址。
DNS 查询:首先查询本地 host,再访问 DNS 服务器将 域名解析成 ip 地址。
建立 TCP 连接。
服务器收到请求后处理,并且构造响应返回给客户端。
客户端接收 HTTP 报文响应。
渲染页面,最后有可能会四次挥手断开连接,也可能不会而是复用连接。
重点来了:
如何理解 TCP 的三次握手与四次挥手?每次握手客户端与服务端是怎样的状态?
为何挥手会出现 2MSL,遇到大量 Socket 处在 TIME_WAIT 或者 CLOSE_WAIT 状态是什么问题?
三次握手与四次挥手的过程是怎样的?
HTTP 的报文格式又是怎样的?
继续阅读本文,且听码哥字节答疑解惑,微信搜索 “码哥字节”,关注公众号更多硬核。
比如【码哥字节】在思否发布的一篇文章的地址:https://segmentfault.com/a/1190000023475177。url 遵守的规则是这个样子
scheme://host.domain:port/path/filename
每个名词的含义如下解释:
scheme 定义应用层协议类型,比如 http、https、 ftp 等;
host 定义域主机(http 的默认主机是 www);
domain 定义因特网域名,比如 segmentfault.com;
port 主机的端口,http 默认是 80, https 默认是 443;
path 服务器上的资源路径;
filename - 定义文档/资源的名称;
浏览器不能直接通过域名找到服务器,只能通过 IP 地址。
那浏览器是如何通过域名查询到我们输入的 url 对应的 IP 呢?
浏览器缓存:按照一定频率缓存 DNS 数据。
操作系统缓存:如果浏览器缓存好啊不到记录则去操作系统中找。
路由缓存:路由器 DNS 缓存。
ISP 的 DNS 服务器:ISP 是互联网服务提供商(Internet Service Provider)的简称,ISP 有专门的 DNS 服务器应对 DNS 查询请求。
根服务器:ISP 的 DNS 服务器还找不到的话,它就会向根服务器发出请求,进行递归查询(DNS 服务器先问根域名服务器.com 域名服务器的 IP 地址,然后再问 .baidu 域名服务器,依次类推)
通过域名解析出 IP 地址以后就要建立 TCP/IP 连接了。
TCP/IP 分为四层,每一层都会加上一个头部再发送给下一层。到了接收方后,对应的每一层则把对应层的头部解析拆除,丢上上一层,跟发送端的过程反过来。
浏览器从地址栏得到服务器 IP,接着构造一个 HTTP 报文,其中包括:
请求行包含请求方法、URL、协议版本
请求报头(Request Header):由 “关键字: 值”对组成,每行一对,关键字与值使用英文 “:” 分割
请求体:请求参数,并不是所有的请求有又请求参数。一般 get 参数 的格式 name=tom&password=1234&realName=tomson,也可以将参数放在 body 里面。
在传输报文之前会先建立 TCP/IP 连接,也就是后面我们要说的三次握手。
在这一层解决了数据可靠传输、及流量控制、拥塞控制。
可靠传输
对于发送方发送的数据,接收方在接受到数据之后必须要给予确认,确认它收到了数据。如果在规定时间内,没有给予确认则意味着接收方没有接受到数据,然后发送方对数据进行重发。
TCP的可靠传输是通过确认和超时重传的机制来实现的,而确认和超时重传的具体的实现是通过以字节为单位的滑动窗口机制来完成。
TCP拥塞控制
TCP协议通过慢启动机制、拥塞避免机制、加速递减机制、快重传和快恢复机制来共同实现拥塞控制。
流量控制
采用通知窗口实现对发送端的流量控制,通知窗口大小的单位是字节。TCP通过在TCP数据段首部的窗口字段中填入当前设定的接收窗口(即通知窗口)的大小,用来告知对方 '我方当前的接收窗口大小',以实现流量控制。
通信双方的发送窗口大小由双方在连接建立的时候商定,在通信过程,双方可以动态地根据自己的情况调整对方的发送窗口大小。
将数据段打包,并加入源及目标的 IP 地址,并且负责寻找传输路线。判断目标地址是否与当前地址处于同一网络中,是的话直接根据 Mac 地址发送,否则使用路由表查找下一跳地址,以及使用 ARP 协议查询它的 Mac 地址。
根据以太网协议将数据分为以“帧”为单位的数据包,每一帧分为两个部分:
标头:数据包的发送者、接受者、数据类型
数据:数据包具体内容
以太网规定了连入网络的所有设备都必须具备“网卡”接口,数据包都是从一块网卡传递到另一块网卡,网卡的地址就是 Mac 地址。每一个 Mac 地址都是独一无二的,具备了一对一的能力。
在传输层传输数据之前需要建立连接,也就是三次握手创建可靠连接。
首先建立链接前需要 Server 端先监听端口,因此 Server 端建立链接前的初始状态就是 LISTEN 状态,这时 Client 端准备建立链接,先发送一个 SYN 同步包,发送完同步包后,Client 端的链接状态变成了 SYN_SENT 状态。Server 端收到 SYN 后,同意建立链接,会向 Client 端回复一个 ACK。
由于 TCP 是双工传输,Server 端也会同时向 Client 端发送一个 SYN,申请 Server 向 Client 方向建立链接。发送完 ACK 和 SYN 后,Server 端的链接状态就变成了 SYN_RCVD。
Client 收到 Server 的 ACK 后,Client 端的链接状态就变成了 ESTABLISHED 状态,同时,Client 向 Server 端发送 ACK,回复 Server 端的 SYN 请求。
Server 端收到 Client 端的 ACK 后,Server 端的链接状态也就变成了的 ESTABLISHED 状态,此时建连完成,双方随时可以进行数据传输。
在面试时需要明白三次握手是为了建立双向的链接,需要记住 Client 端和 Server 端的链接状态变化。另外回答建连的问题时,可以提到 SYN 洪水攻击发生的原因,就是 Server 端收到 Client 端的 SYN 请求后,发送了 ACK 和 SYN,但是 Client 端不进行回复,导致 Server 端大量的链接处在 SYN_RCVD 状态,进而影响其他正常请求的建连。可以设置 tcp_synack_retries = 0 加快半链接的回收速度,或者调大 tcp_max_syn_backlog 来应对少量的 SYN 洪水攻击。
我们只要关注 80 端口与 13743 端口建立的连接断开过程,浏览器通过 13747 端口发送 [FIN, ACK] 这里是不是跟很多网上看到的不一样?
其实是客户端在发送 [FIN] 报文的时候顺带发了一个 [ACK] 确认上次传输确认。
接着服务端通过 80 端口响应了 [ACK] ,然后立马响应 [FIN, ACK] 表示数据传输完了,可以关闭连接。
最后浏览器通过 13743 端口 发送 [ACK] 包给服务端,客服端与服务端连接就关闭了。
具体流程如下图抓包所示:
三次握手与四次挥手
客户端:
SYN_SENT - 客户端发起第 1 次握手后,连接状态为 SYN_SENT ,等待服务端内核进行应答,如果服务端来不及处理(例如服务端的 backlog 队列已满)就可以看到这种状态的连接。
ESTABLISHED - 表示连接处于正常状态,可以进行数据传送。客户端收到服务器回复的 SYN+ACK 后,对服务端的 SYN 单独回复(第 3 次握手),连接建立完成,进入 ESTABLISHED 状态。服务端程序收到第 3 次握手包后,也进入 ESTABLISHED 状态。
FIN_WAIT_1 - 客户端发送了关闭连接的 FIN 报文后,等待服务端回复 ACK 确认。
FIN_WAIT_2 - 表示我方已关闭连接,正在等待服务端关闭。客户端发了关闭连接的 FIN 报文后,服务器发回 ACK 应答,但是没进行关闭,就会处于这种状态。
TIME_WAIT - 双方都正常关闭连接后,客户端会维持 TIME_WAIT 一段时间,以确保最后一个 ACK 能成功发送到服务器端。停留时长为 2 倍的 MSL (报文最大生存时间),Linux 下大约是 60 秒。所以在一个频繁建立短连接的服务器上通常可以看到成千上万的 TIME_WAIT 连接。
服务端:
LISTEN - 表示当前程序正在监听某个端口时。
SYN_RCVD - 服务端收到第 1 次握手后,进入 SYN_RCVD 状态,并回复一个 SYN+ACK(第 2 次握手),再等待对方确认。
ESTABLISHED - 表示连接处于正常状态,可以进行数据传送。完成 TCP3 次握手后,连接建立完成,进入 ESTABLISHED 状态。
CLOSE_WAIT - 表示客户端已经关闭连接,但是本地还没关闭,正在等待本地关闭。有时客户端程序已经退出了,但服务端程序由于异常或 BUG 没有调用 close函数对连接进行关闭,那在服务器这个连接就会一直处于 CLOSE_WAIT 状态,而在客户机已经不存在这个连接了。
LAST_ACK - 表示正在等待客户端对服务端的关闭请求进行最终确认。
TIME_WAIT 状态存在的理由:
划重点了
可靠地实现 TCP 全双工连接的终止 在进行关闭连接四路握手协议时,最后的 ACK 是由主动关闭端发出的,如果这个最终的 ACK 丢失,服务器将重发最终的 FIN,因此客户端必须维护状态信息允 许它重发最终的 ACK。如 果不维持这个状态信息,那么客户端将响应 RST 分节,服务器将此分节解释成一个错误( 在 java 中会抛出 connection reset 的 SocketException)。因而,要实现 TCP 全双工连接的正常终 止,必须处理终止序列四个分节中任何一个分节的丢失情况,主动关闭 的客户端必须维持状 态信息进入 TIME_WAIT 状态。
允许老的重复分节在网络中消逝 TCP 分节可能由于路由器异常而“迷途”,在迷途期间,TCP 发送端可能因确认超时而重发这个 分节,迷途的分节在路由器修复后也会被送到最终目的地,这个 原来的迷途分节就称为 lost duplicate。在关闭一个 TCP 连接后,马上又重新建立起一个相同的 IP 地址和端口之间的 TCP 连接,后一个连接被称为前一个连接的化身 ( incarnation),那么有可能出现这种情况,前一 个连接的迷途重复分组在前一个连接终止后出现,从而被误解成从属于新的化身。为了避免 这个情 况,TCP 不允许处于 TIME_WAIT 状态的连接启动一个新的化身,因为 TIME_WAIT 状 态持续 2MSL,就可以保证当成功建立一个 TCP 连接的时 候,来自连接先前化身的重复分组已 经在网络中消逝。
另外回答断链的问题时,可以提到实际应用中有可能遇到大量 Socket 处在 TIME_WAIT 或者 CLOSE_WAIT 状态的问题。一般开启 tcp_tw_reuse 和 tcp_tw_recycle 能够加快 TIME-WAIT 的 Sockets 回收;而大量 CLOSE_WAIT 可能是被动关闭的一方存在代码 bug,没有正确关闭链接导致的。
简单地说就是
保证 TCP 协议的全双工连接能够可靠关闭;
保证这次连接的重复数据段从网络中消失,防止端口被重用时可能产生数据混淆;
深入分析下 HTTP 报文到底是什么玩意。数据传输都是通过 TCP/IP 协议负责底层的传输工作, HTTP 协议基本不用操心,所谓的 “超文本传输协议” 似乎不怎么例会 “传输” 这个事情,那 HTTP 的核心又是什么呢?
比图 TCP 报文,它在实际要传输的数据之前附加了一个 20 字节的头部数据,存储 TCP 协议必须的额外信息,例如发送方的端口号、接收方的端口号、包序号、标志位等等。
有了这个附加的 TCP 头,数据包才能够正确传输,到了目的地后把头部去掉,就可以拿到真正的数据。这个很容易理解,设置起点与终点,不同协议贴上不同的头部,到了对应目的地就拆下这个头部,提取真正的数据。
与 TCP/UDP 类似需要在传输数据前设置一些请求头,不同的是 HTTP 是一个 “纯文本” 的协议,所有的头都是 ASCII 码的文本,很容易看出来是什么。
再者就是他的请求报文与响应报文的结构基本一样,主要三大部分组成:
起始行(Start Line):描述请求或者响应的基本信息。
Header:使用 key-value 的形式详细说明报文信息。
空行。
消息正文(Entity):传输的数据,图片、视频、文本等都可以。
这其中前两部分起始行和头部字段经常又合称为“请求头”或“响应头”,消息正文又称为“实体”,但与“header”对应,很多时候就直接称为“body”。
敲黑板了
HTTP 协议规定报文必须包含 Header,而且之后必须有一个 “空行”,也就是“CRLF”,十六进制的“0D0A”,可以没有 “body”。
报文结构如下图所示:
截取一段报文:
请求头-起始行
请求行由请求方法字段、URL 字段和 HTTP 协议版本字段 3 个字段组成,它们用空格分隔。例如,GET / HTTP/1.1。
HTTP 协议的请求方法有 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。
GET 是请求方法, “/” 是请求的目标资源,“HTTP/1.1” 请求协议版本号。
GET / HTTP/1.1 翻译成文字大概就是:“hello,服务器,我要请求根目录下的默认文件使用的是 HTTP 1.1 协议版本”。
头部 Header
第二部分就是 Header,组成形式是 key:value,使用自定义头需要注意事项:
header 字段不区分大小写,通常是首字母大写;
字段名不允许有空格,可以使用 “-”,不能使用 “_”;
字段名必须紧接着 “:”,不能有空格,但是 “:” 后面可以有空格。
字段名顺序没有意义;
接收到响应文本 HTML,则开始执行浏览器渲染机制。
不同的浏览器渲染可能有所差异,但是基本按照以下步骤执行:
根据 HTML 解析 DOM 树;
根据 CSS 解析出 CSS 规则树;
结合 DOM 树与 CSS 规则树,生成渲染树;
根据生成的渲染树计算每个节点的信息;
根据节点信息绘制画面展示给用户。
点分享
*请认真填写需求信息,我们会在24小时内与您取得联系。