一个网站访问http的过程?
1 浏览器补全url http://www.jd.com:80/
2 浏览器缓存 查寻
3 本地hosts文件解析如果没有
4 系统DNS缓存如果没有
5 向本地DNS提供商缓存 UDP连接 53端口 如果没有
6 域名根服务器 迭代查寻
7 找到com管理域迭代查寻
8 jd.com管理DNS解析域名 返回给系统 各级DNS可能会缓存解析记录
9 向解析出的IP地址发起访问请求TCP三次握手
10 建立TCP连接后发起http请求
11 服务器响应http请求,浏览器得到html代码
12 如果页面有dns-prefetch(DNS预获取)此功能由html5提供 则预先获取各级域名的解析记录
13 浏览器解析html代码,并请求代码中的资源如js css 图片等
14 浏览器对页面进行渲染呈现给用户
http请求
三次握手建立 TCP 连接:
在 http 工作开始之前,浏览器首先要通过网络与服务器建立连接,该连接是通过 TCP 来完成的。该协议与 IP 协议共同构建 Internet ,即著名的 TCP/IP 协议族,因此 Internet 又被称作是 TCP/IP 网络。 http 是比 TCP 更高层次的应用层协议。根据规则,只有低层协议建立之后才能进行更高次层协议的连接。因此,首先要建立 TCP 连接,一般 TCP 连接的端口号是 80 。在 TCP/IP 协议中,TCP 协议提供可靠的连接服务,采用三次握手建立一个连接:
第一次握手:建立连接时,客户端发送 SYN 包(syn=j)到服务器,并进入 SYN_SENT 状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)
第二次握手:服务器收到 SYN 包,必须确认客户的 SYN(ack=j+1),同时自己也发送一个 SYN 包(syn=k),即 SYN+ACK 包,此时服务器进入 SYN_RECV 状态;
第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(ack=k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED(TCP连接成功)状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据。
一旦建立了 TCP 连接,浏览器就会向服务器发送 http 请求命令。浏览器发送其请求命令之后,还要以头信息的形式向服务器发送一些别的信息。此后,浏览器发送了一空白行来通知服务器,它已经结束了该头信息的发送。
四次挥手终止连接
由于 TCP 连接是全双工的,因此每个方向都必须单独进行关闭。原则是当一方完成它的数据发送任务后,就能发送一个 FIN 来终止这个方向的连接。收到一个 FIN 只意味着这一方向上没有数据流动。一个 TCP 连接在收到一个 FIN 后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
第一次挥手:TCP 客户端发送一个 FIN,用来关闭客户端到服务器的数据传送。
第二次挥手:服务器收到这个 FIN,它发回一个 ACK,确认序号为收到的序号加 1 。和 SYN 一样,一个 FIN 将占用一个序号。
第三次挥手:服务器关闭客户端的连接,发送一个 FIN 给客户端。
第四次挥手:客户端发回 ACK 报文确认,并将确认序号设置为收到序号加 1 。
Http请求数据包格式
请求行 + 请求头 + 数据体
(1)请求行
包含三个内容 method + request-URI + http-version。
method 包含有 post , get, head,delete, put, connect, options, patch, propfind, propatch, mkcol, copy, move, lock, unlock, trace, head。
get
通过请求URI获得资源
post 用于添加新的资源,用于表单提交
put
用于修改某个内容
delete 删除某个内容
connect 用于代理进行传输例如SSL
options 询问可以执行那些方法
patch 部分文档更该
propfind 查看属性
proppatch 设置属性
mkcol 创建集合
copy 拷贝
move 移动
lock 加锁
unlock 解锁
trace 用于远程诊断服务器
head 类似于get,用于检查对象是否存在用于得到元数据
主要介绍get方法和post方法
get方法:
是在url中说明情请求的资源,比如https://www.baidu.com/con?from=self?_t=1466609839126 其中?后的数据就是请求的数据,并且连接用&,get方法也可以提交表单数据,但是提交的数据在url中,其他人可以通过查看历史记录中的url来获取你提交的数据,这样很不安全。
post方法:
传输数据不在url中,而在数据段中出现,并且请求头多了Content-Type和Content-Length,post提交表单数据的时候比get方法更安全。
post方法提交表单和get方法提交表单相比较:
get明文传输,信息附加在url上面,get明文传输,post更加安全
get传输有大小限制,应该是3k,post需要制定传输类型
get多用于获取数据,根据get变量的不同调用不同的数据,post多用于提交数据,提交用户输入的数据
get方法和post方法的区别:
1>Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求。
2>Get是获取信息,而不是修改信息,类似数据库查询功能一样,数据不会被修改。
3>Get请求的参数会跟在url后进行传递,请求的数据会附在URL之后,以?分割URL和传输数据,参数之间以&相连,%XX中的XX为该符号以16进制表示的ASCII,如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密。
4>Get传输的数据有大小限制,因为GET是通过URL提交数据,那么GET可提交的数据量就跟URL的长度有直接关系了,不同的浏览器对URL的长度的限制是不同的。
5>GET请求的数据会被浏览器缓存起来,用户名和密码将明文出现在URL上,其他人可以查到历史浏览记录,数据不太安全。在服务器端,用Request.QueryString来获取Get方式提交来的数据。
6>Post请求则作为http消息的实际内容发送给web服务器,数据放置在请求体中,Post没有限制提交的数据。Post比Get安全,当数据是中文或者不敏感的数据,则用get,因为使用get,参数会显示在地址,对于敏感数据和不是中文字符的数据,则用post。
7>POST表示可能修改变服务器上的资源的请求,在服务器端,用Post方式提交的数据只能用Request.Form来获取。
请求行例如 : GET /icwork/? Search = product HTTP/1.1
(2)请求头
Accept:指浏览器或其他客户可以接爱的MIME文件格式。Servlet可以根据它判断并返回适当的文件格式。
User-Agent:是客户浏览器名称。
Host:对应网址URL中的Web名称和端口号。
Accept-Langeuage:指出浏览器可以接受的语言种类,如en或en-us,指英语。
connection:用来告诉服务器是否可以维持固定的HTTP连接。http是无连接的,HTTP/1.1使用Keep-Alive为默认值,这样,当浏览器需要多个文件时(比如一个HTML文件和相关的图形文件),不需要每次都建立连接
Cookie:浏览器用这个属性向服务器发送Cookie。Cookie是在浏览器中寄存的小型数据体,它可以记载和服务器相关的用户信息,也可以用来实现会话功能。
Referer:表明产生请求的网页URL。如比从网页/icconcept/index.jsp中点击一个链接到网页/icwork/search,在向服务器发送的GET/icwork/search中的请求中,Referer是http://hostname:8080/icconcept/index.jsp。这个属性可以用来跟踪Web请求是从什么网站来的。
User-Agent:是客户浏览器名称。
Content-Type:用来表名request的内容类型。可以用HttpServletRequest的getContentType()方法取得。
Accept-Charset:指出浏览器可以接受的字符编码。英文浏览器的默认值是ISO-8859-1.
Accept-Encoding:指出浏览器可以接受的编码方式。编码方式不同于文件格式,它是为了压缩文件并加速文件传递速度。浏览器在接收到Web响应之后先解码,然后再检查文件格式。
get方法请求头例如:
Accept:image/webp,image/*,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Cookie:PSTM=1466499789; BAIDUID=D3A617EE01FFA9DB9B7E3E5F0D3A01EE:FG=1; BIDUPSID=4AA34EC11075CB66B8BC9792DD422B6F; BDUSS=VCc1M0cVQtYnFGfmxTUW5kVTUydnBZUmhiWFRXbnRlMnpIdWV2ODVxNHZ1WkZYQVFBQUFBJCQAAAAAAAAAAAEAAADkEA1ZtPO3rMfRt6zH0cfRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8salcvLGpXdz; BD_HOME=1; BD_UPN=123353; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; BD_CK_SAM=1; H_PS_PSSID=19292_18286_1458_20318_18241_20369_17942_20388_19690_20417_18560_17001_15560_12277_20253; BDSVRTM=0
Host:www.baidu.com
Referer:https://www.baidu.com/s?wd=http%20%E8%AF%B7%E6%B1%82%E6%95%B0%E6%8D%AE%E7%9A%84%E6%95%B0%E6%8D%AE%E5%8C%85%E6%A0%BC%E5%BC%8F&rsv_spt=1&rsv_iqid=0x9b746a8000022af9&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=cn&tn=baiduhome_pg&rsv_enter=1&oq=http%20%E8%AF%B7%E6%B1%82%E6%96%B9%E5%BC%8Fpost%20url%E6%A0%BC%E5%BC%8F&rsv_t=59fb7cEn5xgK8JFpqQ7F7coy6k6dn5sGpEMj1cDM4oMoy0TGArJ2l3fxOqy6F9lXoqoi&inputT=7936&rsv_pq=ca5859d100027005&rsv_sug3=73&rsv_sug1=12&rsv_sug7=100&rsv_sug2=0&rsv_sug4=32020
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36
post方法的请求头
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8
Authorization:Basic WkEtMTE0MjcyNjAyMDY=
Connection:keep-alive
Content-Length:666
Content-Type:application/json
Host:zhihu-web-analytics.zhihu.com
Origin:http://www.zhihu.com
Referer:http://www.zhihu.com/question/41690822
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36
Request Payload
view source
相比之下多了content-Type 和 Content-Length
Content-Type:表示的是请求报文体的 MIME 类型 ,注:GET的请求消息体是空的 所以不需要指定消息体的MIME类型
Content-Length:表示的是 post的数据的长度
例如请求数据:
1 GET/sample.jspHTTP/1.1
2 Accept:image/gif.image/jpeg,*/*
3 Accept-Language:zh-cn
4 Connection:Keep-Alive
5 Host:localhost
6 User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
7 Accept-Encoding:gzip,deflate
8
第一行为http请求行,包含方法,URI 和http版本
1-7为请求头,包含浏览器,主机,接受的编码方式和压缩方式;第8行表示一个空行 表示请求头结束 这个空行是必须的;
数据体
第9行是数据体,比如是需要查询的信息。
http响应数据包
状态行 + 响应头 + 响应正文
(1)状态行是由:HTTP-Version+Status-Code+Reason-Phrase
比如:HTTP/1.1 200 ok
分别表示http版本 + 状态码 + 状态代码的文本描述
状态码:
1xx 指示信息–表示请求已接收,继续处理
2xx 成功–表示请求已被成功接收、理解、接受
3xx 重定向–要完成请求必须进行更进一步的操作。
4xx 客户端错误–请求有语法错误或请求无法实现。
5xx 服务器端错误–服务器未能实现合法的请求。
(2)响应头:包含服务器类型,日期,长度,内容类型等
Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2003 13:13:33 GMT
Content-Type:text/html
Last-Moified:Mon,6 Oct 2003 13:23:42 GMT
Content-Length:112
(3)响应正文响应正文就是服务器返回的HTML页面
浏览器访问服务器的过程
首先判断要解析域名,但是解析域名之前首先找到域名服务器,根据配置的域名服务器的ip地址判断 这个域名服务器是否在本网络范围内,一般情况下域名服务器都和当前电脑不在同一个局域网范围内,所以当前电脑需要通过网关访问外网。
我们假定 电脑配置了网关ip,那么 首先当前pc需要向这个网关发送查询DNS的数据,但是因为仅仅知道网关的ip还不知道网关的mac地址,所以会首先使用ARP协议查询当前网关的mac地址。这个arp协议数据包是通过广播的形式发送的,也就是说ARp协议数据包中的ip地址就是网关的ip地址(下图中的Target Ipj就是查询目标主机的ip),但是 mac地址全为F。 下图中右上角的位置 DEST ADDR :FFFF FFFF FFFF
image.png
这样当前主机就知道网关的mac地址。此时当前pc发送 dns查询数据包(UDP协议),首先数据包中的ip地址是DNS主机的ip地址,数据包的mac地址就是网关的mac地址,因为是在局域网内发送数据,所以是通过广播的形式发送,然后局域网内的主机都可以接收到这个数据包,但是仅网关的mac地址匹配,所以网关可以收到这个数据包。然后网关根据路由表和数据包中DNS服务器的ip地址查询路由表得到 下一条路由器的ip地址,如果此时没有下一条路由器的mac地址,那么就使用arp广播发送查询下一条路由器的mac地址。
这样整个过程就可以实现将查询DNS请求数据包发送给DNS 主机,DNS主机解析之后返回数据。DNS解析之后就得到了这个DNS域名对应 的ip。
需要说明的是:
(1) ARP协议是局域网内的 ip地址到mac地址解析协议,注意是局域网内使用的,arp请求是多播,主机发送一个arp请求 该局域网内的所有主机都可以收到,但是仅ip地址匹配的主机会将自己的mac地址放到arp
然后当前pc 发送Http请求,这个请求底层使用tcp协议,数据包中 的ip地址是web服务器的ip地址,mac地址是网关的mac地址。 事实上 当前pc首先 判断 web服务器的ip 和当前主机是否在同一个局域网内,如果在同一个局域网内(也就是使用当前pc的子网掩码与上web服务器的ip地址,所得结果是否等于当前pc所在子网的网络号),如果是处于同一个局域网,那么直接使用arp协议获取这个web服务器的的mac 地址,然后通过硬件广播的形式发送请求就可以了。但是大多数情况下web服务器 和本机不在同一个 局域网内,所以当前pc需要将数据包的ip地址设置为web服务器的ip地址,然后将mac地址设置为网关的mac地址,通过广播的方式交给网关处理。
网关收到后就根据数据包的目的ip地址查询下一条路由器,更改数据的目的mac地址,转发数据包给下一条。
整个过程就是数据传送的过程。
当然, 在当前pc 请求web数据之前需要首先和web服务器建立 tcp连接,这个过称就是三次握手的过程。
三次握手建立之后 发送get请求获取页面数据,服务器返回页面数据,浏览器加载渲染, 最终超过一定 的时间之后 通过4次挥手断开Http连接
特别强调的一点是: 当三次握手建立成功之后,客户端发出get请求 ,浏览器接收到get请求之后需要对这个请求进行确认,也就是返回一个确认数据,然后才发回页面数据,客户端接收到页面数据之后也要发回一个对页面数据的确认。 并不是说客户端发愁get请求 浏览器返回页面数据 仅这两个过程。 http是基于tcp的,底层都要有确认。
虚拟地址空间是通过页表(Page Table)映射到物理内存,页表由操作系统维护并被处理器引用。内核空间在页表中拥有较高特权级,因此用户态程序试图访问这些页时会导致一个页错误(page fault)。在Linux中,内核空间是持续存在的,并且在所有进程中都映射到同样的物理内存。内核代码和数据总是可寻址,随时准备处理中断和系统调用。与此相反,用户模式地址空间的映射随进程切换的发生而不断变化。
以下就是虚拟地址空间的详细布局图: