一次http请求的全过程

转自:微点阅读 https://www.weidianyuedu.com

请求处理过程:

域名解析->建立连接->接收请求->处理请求->访问资源->构建响应报文->发送响应报文->记录日志

域名解析:顺序

检查浏览器自身DNS缓存-->操作系统DNS缓存-->hosts文件--DNS解析

DNS解析是先请求根服务器查找,若没有则查找次一级,知道找到为止,返回一个正确的ip地址。

建立连接

得到IP地址后,浏览器会开启一个随机端口向web服务器的80端口发起tcp连接请求,经过三次握手后建立TCP连接,然后浏览器发起http请求。

接收请求

接收请求所要完成的工作就是接收来自网络中的请求报文中对某一资源的一次请求过程,其接收请求的模型包括以下几类:

单进程I/O模型 启动一个进程处理用户请求,而且一次只处理一个,多个请求被串行响应。

多进程I/O模型 并行启动多个进程,每个进程处理一个请求。

复用I/O结构 一个进程响应n个请求

多线程模型:一个进程生成n个线程,每个线程响应一个用户请求

事件驱动:event-driven

复用的多线程I/O结构:启动多个m线程,每个进程响应n个请求

处理请求

对请求报文进行分析,并获取请求的资源及请求方法等相关信息

访问资源

在对请求进行处理时一般需要 访问后端资源

构建响应报文

在得到请求的结果之后,开始构建响应报文。响应报文中包含有响应状态码、响应首部。如果生成了响应主体的话,还包括响应主体,这时还有一个较为重要的要点,就是资源访问重定向问题。

web服务构建的响应并非客户端请求的资源,而是资源的另外一个访问路径:可分为永久重定向和临时重定向。

发送响应报文

响应报文构建完成之后,发送响应报文。

记录日志

最后,当事物结束之后,Web服务器会在日志文件中添加一个条目,来描述已经执行的事物

TCP三次握手

建立连接、传输数据、断开连接

  1. 建立TCP连接很简单,通过三次握手便可以建立连接

  1. .建立好连接之后,开始传输数据。TCP数据传输牵涉到的概念很多;超时重传,快速重传、流量控制、拥塞控制等等。

  1. 断开连接的过程也很简单,通过四次握手断开连接的过程

三次握手建立连接:

第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认 。

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHD状态,完成三次握手。

握手过程传送的包中不包含数据,三次握手完毕之后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信上方中的任何一方主动关闭连接之前,TCP连接都将被一直保持下去。

传输数据过程:

a.超时重传 超时重传机制用来保证TCP传输的可靠性。每次发送数据包时。发送的数据报都有seq号,接收端收到数据后,会回复ack进行确认,表示某一seq号数据已被收到,发送方在发送了某个seq包后,等待一段时间,如果没有收到对应的ack回复,就会认为报文已经丢失,会重试这个数据包。

b.快速重传 接收数据一方发现有数据包丢失了,就会发送ack报文告诉发送端重传丢失的报文。如果发送端连续收到标号相同的ack包,则会触发客户端的超时重传,可以发现超时重传是发送端在傻等超时,然后触发重传,而快速重传则是接收端主动告诉发送端数据没有收到,然后触发发送端重传机制。

c.流量控制 这里主要说TCP滑动窗流量控制。TCP头里面有一个字段叫Window,又叫Advertised-Window,这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。滑动窗口是可以提高TCP传输效率的一种机制。

d.拥塞控制 滑动窗口用来做流量控制。流量控制只关注发送端和接收端自身的情况,而没有考虑整个网络的通信情况。拥塞控制,则是基于整个网络来考虑的。考虑一下这样的场景:某一时刻网络上的延时突然增加,那么,TCP对这个事件作出的应对只有重传数据,但是重传只会导致整个网络的负担更重,于是会导致更大的延迟以及更多的丢包。于是,这个情况就会进入恶性循环被不断放大。试想一下,如果一个网络内有成千上万的TCP连接都这么行事,那么马上就会形成“网络风暴”,TCP这个协议就会拖垮整个网络。为此,TCP引入了拥塞控制策略,拥塞策略算法主要包括:慢启动,拥塞避免,拥塞发生,快速恢复。

四次挥手断开连接

第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方,我已经不会再给你发送消息了(当然,在fin包发送之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但此时主动关闭方还可以接收数据。

第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号+1(与SYN相同,一个FIN占用一个序号)。

第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,就是告诉主动关闭方,我的数据也发送完了,不会再给你发送数据了。

第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。

猜你喜欢

转载自blog.csdn.net/hdxx2022/article/details/129792743
今日推荐