当前位置: 首页 > 科技观察

输入网址回车,最后发生了什么

时间:2023-03-21 23:19:45 科技观察

详情输入网址回车,后台发生了什么。透析HTTP协议与TCP连接之间千丝万缕的关系。为什么掌握三次握手和四次挥手?time_wait的意义是什么?重点问题全面图解,面试再也不用担心问这个问题了。大致处理URL解析。DNS查询。TCP连接。服务器处理请求。客户端收到HTTP消息响应。页面渲染的重点来了:如何理解TCP的三次握手和四次握手?每次握手客户端和服务器的状态是什么?挥手时为什么会出现2MSL,大量Sockets处于TIME_WAIT或CLOSE_WAIT状态时是什么问题?三次握手四次挥手的过程是怎样的?HTTP的报文格式是什么?继续阅读本文,听码宝答疑,微信搜索“码宝”,关注公众号获取更多硬核。URL解析地址解析:首先判断你输入的是合法的URL还是要搜索的关键字,根据你输入的内容进行自动补全、字符编码等操作。HSTS由于安全隐患,HSTS用于强制客户端使用HTTPS访问页面。详见:你所不知道的HSTS[1]。其他操作浏览器还会进行一些额外的操作,比如安全检查和访问限制(以前国产浏览器限制996.icu)。查看缓存DNS查询浏览器缓存:首先查看是否在缓存中,如果不在,调用系统库函数查询。操作系统缓存:操作系统也有自己的DNS缓存,但在此之前,它会检查本地Hosts文件中是否存在该域名,如果不存在,则向DNS服务器发送查询请求。路由器缓存。ISPDNS缓存:ISPDNS是在客户端计算机上设置的首选DNS服务器,大多数情况下它们都会有缓存。根域名服务器查询在前面所有步骤都没有缓存的情况下,本地DNS服务器会将请求转发到Internet上的根域。下图很好地说明了整个过程:需要注意的是:它在往下走的过程中并不返回,只有在得到最终结果时才返回信息(从浏览器到本地DNS服务器的过程)。迭代法是从本地DNS服务器向根域名服务器查询的方法。什么是DNS劫持?前端dns-prefetch优化TCP连接建立和断开。TCP/IP分为四层。发送数据时,每一层都要对数据进行封装:应用层:发送HTTP请求,浏览器从地址栏获取服务器IP,然后构造一个HTTP报文,其中包括:请求头(RequestHeader):请求方法、目标address,protocoltofollow等requestbody,requestparameters,比如body中的参数Transportlayer:TCPtransportmessage传输层会InitiateaTCPconnectiontotheserver.为了方便传输,数据会被分割(以消息段为单位)并编号,以便服务器在收到消息时能够准确还原消息信息。在建立连接之前,首先会进行一次TCP三次握手。网络层:IP协议查询MAC地址打包数据段,并添加源IP地址和目的IP地址,负责寻找传输路径。判断目标地址是否与当前地址在同一网络,如果是,则直接根据Mac地址发送,否则使用路由表寻找下一跳地址,使用ARP协议查询其Mac地址.链路层:以太网协议按照以太网协议将数据以“帧”为单位划分成数据包,每个帧分为两部分:Header:数据包的发送方、接收方和数据类型Data:具体内容数据包的Mac地址以太网规定所有接入网络的设备都必须有一个“网卡”接口,数据包从一个网卡传递到另一个网卡,网卡的地址就是Mac地址。每个Mac地址都是唯一的,并且具有一对一的功能。主要请求流程:浏览器从地址栏获取服务器的IP和端口号;浏览器通过三次TCP握手与服务器建立连接;浏览器向服务器发送消息;文件被发送到浏览器;浏览器解析消息,将输出呈现到页面;三向握手需要在传输层传输数据之前建立连接,即三向握手创建可靠连接。首先,服务器在建立链接之前需要先监听端口,所以服务器在建立链接之前的初始状态是LISTEN状态。此时客户端准备建立链接,首先发送一个SYN同步包。发送完同步包后,客户端的链接状态变成了SYN_SENT状态。服务端收到SYN后同意建立连接,并会回复一个ACK给客户端。由于TCP是双工传输,服务器端也会同时向客户端发送一个SYN,请求服务器端建立到客户端的链接。发送ACK和SYN后,服务器的链接状态变为SYN_RCVD。客户端收到服务器的ACK后,客户端的链路状态变为ESTABLISHED。同时客户端向服务器发送ACK并回复服务器的SYN请求。服务器端收到客户端的ACK后,服务器端的链路状态变为ESTABLISHED状态。此时连接建立完成,双方可以随时传输数据。面试的时候需要明白三次握手是建立双向链接,需要记住client和server之间的链接状态变化。另外,在回答建立连接的问题时,可以提到SYNflood攻击的原因,即服务器收到客户端的SYN请求后,发送ACK和SYN,但客户端没有回复,导致服务器上出现大量链接。SYN_RCVD状态,进而影响其他正常请求的连接建立。可以设置tcp_synack_retries=0来加速半链接的回收,或者增加tcp_max_syn_backlog来应对少量的SYNflood攻击。我们只需要关注80端口和13743端口断开连接的过程,浏览器发送[FIN,ACK]这和网上看到的不一样吗?实际上,客户端在发送[FIN]报文时,会发送一个[ACK]来确认最后一次发送确认。然后服务器通过80端口响应[ACK],然后立即响应[FIN,ACK]表示数据传输完成,可以关闭连接了。最后浏览器通过13743端口向服务器发送[ACK]包,客户端与服务器的连接关闭。具体过程如下图抓包所示:三次握手四次挥手客户端:SYN_SENT——客户端发起第一次握手后,连接状态为SYN_SENT,等待服务器内核响应,如果服务器来不及处理(例如服务器的积压队列已满)您可以看到处于这种状态的连接。ESTABLISHED-表示连接处于健康状态并且可以进行数据传输。客户端收到服务器回复的SYN+ACK后,单独回复服务器的SYN(第三次握手),连接建立,进入ESTABLISHED状态。服务器程序收到第三次握手包后,也进入ESTABLISHED状态。FIN_WAIT_1-客户端发送FIN消息关闭连接后,等待服务器回复ACK确认。FIN_WAIT_2-表示我们已经关闭连接并正在等待服务器关闭。客户端发送FIN报文关闭连接后,服务端发回ACK响应,但并没有关闭,会一直处于这个状态。TIME_WAIT——双方正常关闭连接后,客户端会保持一段时间TIME_WAIT,以保证最后一个ACK能够成功发送给服务端。驻留时间是MSL(maximummessagelifetime)的两倍,在Linux下约为60秒。所以在一个频繁建立短连接的服务器上,通常可以看到上千个TIME_WAIT连接。Server:LISTEN-指示当前程序何时正在侦听某个端口。SYN_RCVD——服务器收到第一次握手后,进入SYN_RCVD状态,并回复SYN+ACK(第二次握手),然后等待对方确认。ESTABLISHED-表示连接处于健康状态并且可以进行数据传输。完成TCP3次握手后,连接建立,进入ESTABLISHED状态。CLOSE_WAIT-表示客户端已经关闭连接,但是本地还没有关闭,正在等待本地关闭。有时客户端程序已经退出,但是服务端程序因为异常或者bug没有调用close()函数关闭连接,那么连接在服务端会一直处于CLOSE_WAIT状态,但是连接并没有存在于客户端。LAST_ACK-表示客户端正在等待服务器关闭请求的最终确认。TIME_WAIT状态存在的原因是着眼于可靠实现TCP全双工连接的终止。在执行关闭连接的四次握手协议时,最后一个ACK由主动关闭端发送。如果最后的ACK丢失了,服务器会重新发送最后的FIN,所以客户端必须维护状态信息以允许它重新发送最后的ACK。如果不维护此状态信息,则客户端将响应一个RST小节,服务器会将此小节解释为错误(在java中将抛出连接重置的SocketException)。因此,要实现TCP全双工连接的正常终止,必须处理四段终止序列中任意一段丢失,主动关闭的客户端必须维护状态信息,进入TIME_WAIT状态.允许旧的重复段在网络中消失。由于路由器异常,TCP段可能会“丢失”。在丢失期间,TCP发送方可能会由于确认超时而重发该报文段。路由器修复后丢失的网段也会恢复。发送到最终目的地,这个原始丢失的部分被称为丢失的副本。关闭一个TCP连接后,立即重新建立相同IP地址和端口的TCP连接,后一个连接称为前一个连接的化身,那么可能会出现这种情况,前一个Linkedstrayrepeatgroups出现在前一个链接被断开之后终止,从而被误解为属于新的化身。为了避免这种情况,TCP不允许一个处于TIME_WAIT状态的连接开始新的incarnation,因为TIME_WAIT状态持续2MSL,这样可以保证当一个TCP连接成功建立时,从前一个incarnation中重复的数据包的连接在网络中消失了。另外,在回答断链的问题时,可以提到在实际应用中,可能会有大量的Sockets处于TIME_WAIT或者CLOSE_WAIT状态。一般开启tcp_tw_reuse和tcp_tw_recycle可以加快TIME-WAITSockets的回收;而大量的CLOSE_WAIT可能是被动关闭方的代码bug,没有正确关闭连接。简单的说就是保证TCP协议的全双工连接能够可靠的关闭;保证本次连接的重复数据段从网络中消失,防止端口复用时数据混乱;服务器处理请求并响应HTTP报文,深入分析什么是HTTP报文。数据传输是通过TCP/IP协议完成的,HTTP协议基本不用管。所谓“超文本传输??协议”,好像很多时候都没有“传输”,那么HTTP的核心是什么呢?与TCP报文相比,它在实际要传输的数据之前附加了一个20字节的头部数据,存储了TCP协议所必需的附加信息,如发送方的端口号、接收方的端口号、数据包序列数,和标志位等待。有了这个额外的TCP头,数据包就可以正确传输,到达目的地后去掉头就可以得到真正的数据。这很容易理解。设置起点和终点,针对不同的协议粘贴不同的header,到达对应的目的地时去掉header,提取真正的数据。与TCP/UDP类似,在传输数据之前需要设置一些请求头。不同的是,HTTP是一个“纯文本”协议,所有的头部都是ASCII文本,很容易看出来。再者,他的请求报文和响应报文的结构基本相同,主要由三部分组成:起始行(StartLine):描述了请求或响应的基本信息。Header:使用key-value的形式详细说明消息信息。空行。消息文本(Entity):要传输的数据,图片、视频、文本等一应俱全。其中,起始行和头字段的前两部分常统称为“请求头”或“响应头”,消息文本也称为“实体”,但对应于“头”,它通常直接称为“身体”。HTTP协议规定报文必须包含头部,后面必须有“空行”,即十六进制的“CRLF”、“0D0A”,不需要“body”。消息结构如下图所示:截取一段消息:请求头-起始行请求行由三个字段组成:请求方法字段、URL字段和HTTP协议版本字段,三者之间用空格隔开。例如,获取/HTTP/1.1。HTTP协议的请求方式有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。GET是请求方式,“/”是请求的目标资源,“HTTP/1.1”是请求协议的版本号。GET/HTTP/1.1翻译成文本大致是:“你好,服务器,我想请求根目录下的默认文件使用HTTP1.1协议版本”。Header的第二部分是Header,由key:value组成。使用自定义标头时的注意事项:标头字段不区分大小写,通常首字母大写;字段名不允许有空格,可以使用“-”。“_“不能使用;字段名后面必须紧跟“:”,不能有空格,但“:”后可以有空格。字段名的顺序是没有意义的;浏览器接收响应并呈现数据。浏览器收到服务器的响应资源后,对资源进行解析。先看Response头,根据不同的状态码做不同的事情(比如上面说的重定向)。如果响应资源是压缩的(比如gzip),也需要解压。然后,缓存响应资源。接下来根据响应资源中的MIME[3]类型解析响应内容(例如HTML和Image有不同的解析方式)。接下来,呈现接收到的数据。不同的浏览器不完全一样,但是大体的流程是一样的:如果你看完后觉得对你有帮助,希望大家多多分享,点个赞,看质量。妓女。关注【CodegeByte】解锁更多硬核。