浏览器怎么解析http报文(通过一次浏览器请求)
浏览器怎么解析http报文(通过一次浏览器请求)1.1.1:http代表协议名称以http://user:password@localhost:9009/dir/name.html为例file协议(本地文件)那我们现在知道了URL的大体概念之后,咱们可以进行第一个步骤1.浏览器解析URL:
还记得几年前刚刚工作的我每天上班的第一件事就是打开浏览器,浏览一些军事,财经方面的新闻。那个时候对TCP/IP还不是很清楚,为什么明明是TCP协议要和IP一起,他们为什么客户端连接服务端需要指定ip和端口号,服务端连接客户端的时候不用指定端口号呢?为什么要三次握手?为什么TCP能保证消息的可靠性。我在问自己这是为什么,没想到几年过去了比起几年前更加迷惑!哈哈开玩笑的。那么当我们通过浏览器发送一次网络请求的时候到底发送了什么事情呢?
当我们开发web应用时,首先会在浏览器上输入http://IP地址 端口号和资源目录,这种连接叫做URL,其实浏览器还可以处理像FTP MAILTO等协议,当然这里咱们还是要关注下HTTP协议,毕竟是web居多。下图为不同协议的URL(URL(uniform resource locator)以及各个部分含义
HTTP协议
FTP协议
file协议(本地文件)
那我们现在知道了URL的大体概念之后,咱们可以进行第一个步骤
1.浏览器解析URL:
以http://user:password@localhost:9009/dir/name.html为例
1.1.1:http代表协议名称
1.1.2://后面user:password代表的服务器的用户名和密码(可省略大部分情况都是//直接跟服务器域名)
1.1.3 @后面是服务器域名和端口号 (端口号可以sheng'l)
1.1.4端口号后面/之后的是文件目录(可省略)
刚刚1.1.4说文件目录可以省略,像这样http://localhost:9009/没有文件目录的URL访问的是什么,很简单这需要服务器上设置一个默认文件, 一般来讲都叫index.html或者是default.html 这样写http://localhost:9009 也是允许的。我们都知道/代表的是web服务器的root目录,那这样的请求呢,
http://localhost:9009/name 是不是说一个叫name的文件名字呢?实际上这个name不一定是文件名称,也有可能是目录,因为操作系统不允许同时存在name的目录和文件名。
2.URL在解析之后,因为我们使用的是HTTP协议,浏览器会生成HTTP消息
在这里简单坐下介绍:消息头大体如下:
Http主要方法如下:
HTTP的主要方法
3.在浏览器端生成HTTP协议之后,虽然浏览器能够解析URL,但是浏览器并不具备将消息发送到网络中的功能,所以浏览器需要委托操作系统中一个叫做协议栈的程序发送请求,目前为止我们还有一件事需要做,那就是查询服务器对应的ip地址 IP地址由四组8比特(1字节)的数字组成,因为人们很难记住这些ip地址,所以就产生了ip地址和域名并用的情况。所以我们需要用到DNS解析域名,但是系统怎么知道去哪里找DNS服务器呢,在windows系统中实际上设置了DNS服务器的地址,因为DNS概念还要涉及到根服务器所以简单表述,不在做过多的解释。
DNS客户端(UDP协议)
4.收发消息
当浏览器委托协议栈查询到服务器IP地址之后,我们就可以收发消息了,收发操作大概分为四个部分
4.1:创建套接字(socket)
上面说到协议栈查询了域名对应的IP地址后,接着协议栈创建套接字 并申请一块内存空间,用来存储IP地址,端口号,通信操作状态,以及代表本次请求的描述符等。比如说请求发送了很久没有回应,这个时候我们不能一直等待,需要一段时间后重发。协议栈需要这些状态来判断它的进一步行动。
4.2:连接(服务器和客户端相互感知对方的存在,并初始化控制信息)
当我们创建完成套接字(socket)之后,开始尝试连接,何为连接?简单来说就是双方交互信息,你的ip地址和端口号,我的ip地址和端口号,我的SYN ack,seq。你是否收到了我的信息等,俗称三次握手过程如下:
三次握手过程
再看下TCP协议头部
TCP头部信息
TCP头部通常为20字节,带上选项部分,最大不超过60字节,下面逐一进行解释。
16位源端口号:指发送端的端口号
16位目的端口号:指目的端的端口号
4位头部长度:同IP头部,表示TCP头部的大小,以4字节为单位。
32位序列号:TCP通信过程中,通过序列号来保证传输过程中数据的有序性
32位确认号:用以对接受到的报文进行确认
保留6位
URG:表示紧急指针
ACK:表示确认号
PSH:通知对端立即从缓冲区取走数据
SYN:表示请求建立连接
FIN:标志要通知对端本端的数据发送要关闭
16位窗口大小:TCP流量控制的手段,告诉发送方本端的接收端缓冲区还能接受多少数据
16位校验和:由发送方填充,接收端用CRC校验算法,用以检查TCP报文在传输过程中是否有损坏
还记得我在片头的疑问吗?为什么客户端连接服务端需要ip地址和端口号,而服务器连接客户端不需要知道端口号 其实答案就是在连接这个过程中客户端已经告知服务端了。
4.3:收发数据(通信阶段)
让我们来看下目前整理下发送的机制:客户端发送数据到服务端,服务端确认在通知客户端,如此反复,直到数据发送完毕,就像这样
如果数据不算多的话这样发送也还可以,但是吞吐量还是下降了,而且在谈到这里的时候需要插上一句以太网中的数据包最大只有1500字节大小,这部分叫MTU,减去MAC协议头部,IP协议头部,TCP协议头部才是发送数据真正的大小,这部分叫做MSS
所以大数据就需要拆分,分成多个窗口发送,为了提高吞吐量TCP允许在发送数据之后 不用等待ack连续发送多个窗口,这种方式叫做滑动窗口。
大体流程如下:
我们可以看到应用程序将数据切分为多个数据块,分别发送,每次发送固定大小1640个 还记得上面讲到TCP头部的时候有个窗口大小吗?这1640就是协议的窗口大小。这个窗口大小的值不是固定,取决于消费方的消费速度,一般来说窗口大小是由接收方确定的,在连接阶段发送给发送方。可能有的朋友会问那怎么组装呢,相信有的朋友会有这样的疑问,其实做过网络编程的同学肯定会了解,TCP协议会把零散的数据块按照顺序还原,而这这些数据会存在接收方的缓冲区,而后应用程序会读取缓冲区的数据,在经过解析就还原了发送的数据了。
4.4: 断开阶段
断开连接根据TCP协议可以由客户端和服务端任意一方断开,阶段大致过程如下:
4.4.1:第一次:客户端请求断开FIN seq=u
4.4.2:第二次:服务器确认客户端的断开请求ACK ack=u 1 seq=v
4.4.3:第三次:服务器请求断开FIN seq=w ACK ack=u 1
4.4.4:第四次:客户端确认服务器的断开ACK ack=w 1 seq=u 1
断开操作有一点要注意就是通信已经结束了,创建的套接字(socket)也就不使用了,但是套接字不会立即删除,设想下客户端最后一次发送ack到服务器,而这个ack号丢失了,服务器没有接到ack 客户端可能要重发一次,而这个套接字也已经删除了,这个时候恰巧新创建的套接字也分配到了同一个端口号,这个时候客户端发送的FIN=1刚刚到,会发生什么呢?
我们来看下TCP/IP四层协议