从输入URL到页面展示发生了什么?
大致过程:
1. DNS域名解析
2. 建立TCP连接
3. 客户端发送HTTP请求
4. 服务器处理请求并返回HTTP响应
5. 浏览器解析渲染页面
6. 断开TCP连接
万维网的大致工作过程图
打开一个网页,整个过程会使用哪些协议
在互联网使用的各种协中最重要和最著名的就是 TCP/IP 两个协议。现在人们经常提到的TCP/IP并不一定单指TCP和IP这两个具体的协议,而往往表示互联网所使用的整个TCP/IP协议族。
说明:本文主要是为了将计算机网络中所学的协议穿起来。
统一资源定位符URL
URL是对可以从Internet上得到的资源的位置和访问方法的一种简洁表示,也是指明Internet上任何种类信息的标准。它定义四种要素:方法、主机、端口和路径(方法://主机:端口/路径)。
方法:用来读取文档的协议。
主机:存放信息的计算机。万维网页面通常存储在以“www”为起始别名的计算机中。
端口:服务器应用程序的端口号。
路径:信息所存放的路径名。
5、应用层
在浏览器(HTTP客户端)输入URL例如【www.leixingke.com】默认的给加了HTTP:// 实际上是【http://www.leixingke.com/】
应用层的浏览器决定向 DNS 服务器请求解析域名【www.leixingke.com】
DNS 运行在 53 号端口,于是浏览器会创建一个 UDP 套接字,标识该套接字是『目的 IP 地址』加【目的端口】。例如【www.leixingke.com:80】就是一个套接字。
套接字本质上就是为了唯一标识应用层进程,就是为了让响应报文能够找到目的地。
接着,浏览器将 DNS 请求报文封装好推入套接字,开始DNS 解析。
DNS域名解析系统
DNS使用TCP和UDP,端口号都是53,但它主要使用UDP,服务器之间备份使用TCP,全球只有13台根服务器,一个主根服务器在美国,其他12台位辅根服务器,DNS服务器依据角色可以分为:主DNS,从DNS,缓存DNS服务器,DNS转发器。
1、正向解析:根据主机名称(域名)查找对应的IP地址
2、反向解析:根据IP地址查找对应的主机域名
DNS两种解析方式
递归解析 (转发给其他服务)
递归解析:客户端(解析器)可以从名称服务器中请求递归应答。这意味着解析器期望服务器提供最终答案。如果服务器是这一域名的授权者,它会检查它的数据库并做出响应。如果服务器不是授权者,它会把请求发送给其他服务器(通常是父服务器),并等待响应。如果父服务器是授权者,它就做出响应。否则它仍把查询发送给其他服务器。 当查询最终得到解析后,响应就回溯知道最终到达发出请求的客户端。这就是递归解析(recursive resolution)。
迭代解析 (自己请求)
迭代解析:如果客户端没有请求递归查询,则映射以迭代的形式完成。如果服务器是名称的授权者,则它发送应答; 反之,它会返回一个它认为能够解析该查询的服务器的IP地址(给客户端),由客户端负责向第二台服务器重复发送请求。如果新的地址解析服务器能够解析这一问题, 那么就用IP地址响应这一请求。否则,它再向客户端返回新的地址解析服务器的IP地址。这时,客户端必须向第三台服务器重复该请求。 这一过程称为迭代解析(iterative resolution)。

最终我们得到域名【www.leixingke.com】的 IP 地址。
接着,浏览器将请求数据打包成一个HTTP协议格式的数据包。然后创建一个 TCP 套接字socket。将HTTP报文发送给运输层。
HTTP协议(超文本传输协议)
所谓协议,就是指双方遵循的规范。例如HTTP协议,就是浏览器和服务器之间进行“沟通”的一种规范。
超文本传输协议主要用于访问WWW上的数据。协议以普通文本、超文本、音频、视频等格式传输数据。称为超文本协议,原因是在应用环境中,它可以快速的在文档之间跳转。HTTP在公认端口80上使用TCP服务。
HTTP协议从诞生到现在已经有若干个版本,其中最关键的版本为:HTTP/1.0、HTTP/1.1,其中 HTTP/1.1版本 是当前使用的主流版本。
HTTP协议在运输层的使用 TCP协议提供的服务。
HTTP请求它主要发生在客户端。发送HTTP请求的过程就是构建HTTP请求报文并通过TCP协议中发送到服务器指定端口(HTTP协议80/8080, HTTPS协议443)。HTTP请求报文是由四部分组成: 请求行, 请求报头,空行和请求正文。
HTTP响应报文也是由四部分组成: 状态码, 响应报头,空行和响应报文。
请求报文格式如下:

响应报文格式如下:

可参考:HTTP超文本传输协议
google浏览器查看
请求报文

响应报文

HTTP的方法
方法 |
描述 |
GET |
从指定的资源请求数据。 |
POST |
向指定的资源提交要被处理的数据。 |
HEAD |
与 GET 相同,但只返回 HTTP 报头,不返回文档主体。 |
PUT |
上传指定的 URI 表示。 |
DELETE |
删除指定资源。 |
OPTIONS |
返回服务器支持的 HTTP 方法。 |
CONNECT |
把请求连接转换到透明的 TCP/IP 通道。 |
GET与POST区别
1. GET是从服务器上获取数据,
POST 是向服务器传送数据。
2. GET请求把参数包含在URL中,将请求信息放在URL后面,POST请求通过request body传递参数,将请求信息放置在报文体中。
3. GET安全性非常低, GET设计成传输数据,一般都在地址栏里面可以看到,POST安全性较高, 在地址栏看不到。(如果没有加密,他们安全级别都是一样的,随便一个监听器都可以把所有的数据监到。)
4. GET请求在URL中传送的参数是有长度限制的,而POST没有(在浏览器中非HTTP规定的)。
get有长度限制为1024B吗?网上大多是这么说的,很长一段时间我也以为是HTTP规定的。
实际上HTP get方法提交的数据大小长度并没有限制,Http协议规范没有对URL长度进行限制。目前说的get长度有限制,是特定的浏览器及服务器对它的限制。
POST是没有大小限制的(浏览器没有)。HTTP协议规范也没有进行大小限制,起限制作用的是服务器处理程序的处理能力。
5. GET请求能够被缓存,GET请求会保存在浏览器的浏览记录中,以GET请求的URL能够保存为浏览器书签,post请求不具有这些功能。
6. HTTP的底层是TCP/IP,GET/POST都是TCP链接。GET和POST能做的事情是一样的。
7.GET产生一个TCP数据包,对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
POST产生两个TCP数据包,对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据),并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
HTTP状态码:
1xx:指示信息–表示请求已接收,继续处理。
2xx:成功–表示请求已被成功接收、理解、接受。
3xx:重定向–要完成请求必须进行更进一步的操作。
4xx:客户端错误–请求有语法错误或请求无法实现。
5xx:服务器端错误–服务器未能实现合法的请求。
HTTP常用的状态码 |
|
消息: |
描述: |
200 OK |
请求成功(其后是对GET和POST请求的应答文档。) |
300 Multiple Choices |
多重选择。链接列表。用户可以选择某链接到达目的地。最多允许五个地址。 |
301 Moved Permanently |
所请求的页面已经转移至新的url。 |
400 Bad Request |
服务器未能理解请求。 |
401 Unauthorized |
被请求的页面需要用户名和密码。 |
403 Forbidden |
对被请求页面的访问被禁止。 |
404 Not Found |
服务器无法找到被请求的页面。 |
500 Internal Server Error |
请求未完成。服务器遇到不可预知的情况。 |
万维网的大致工作工程
HTTP长连接
在HTTP/1.0时期,每次HTTP请求都会创建一个新的TCP连接,请求完成后之后这个TCP连接就会被关闭。这种通信模式的效率不高,所以在HTTP/1.1中,引入了HTTP长连接的概念,使用长连接的HTTP协议,会在响应头加入Connection:keep-alive。这样当浏览器完成一次请求后,浏览器和服务器之间的TCP连接不会关闭,再次访问这个服务器上的网页时,浏览器会继续使用这一条已经建立的连接,也就是说两个请求可能共用一个TCP连接。省去了下一次的TCP三次握手。
HTTP/1.1中的长连接依然没有解决 head of line blocking 的问题,后面的连接必须等待前面的返回了才能够发送,这个问题直到HTTP/2.0采取二进制分帧编码方式才彻底解决。
Cookie和Session
UDP协议具有不可靠性和不安全性,这很难满足web应用的需要。而TCP协议是基于连接和三次握手的,虽然具有可靠性,但也比较消耗资源。
场景:如果几十万个客户端和服务器一直保持连接状态,那服务器需要多高的要求才能满足承载!
于是就产生了HTTP协议。基于TCP的可靠性连接。在请求之后,服务器端立即关闭连接、释放资源。这样既保证了资源可用,又满足了安全性和可靠性。
正因为HTTP在请求之后,服务器端立即关闭连接、释放资源,所以大家通常说http协议是“无状态”的,也就是“服务器不知道你客户端干了什么”,其实很大程度上是基于性能考虑的。于是后面就有了cookie和session这些技术。
HTTP协议是无状态的,请求与请求之间是没有关系的。因此HTTP协议需要一种技术让请求与请求之间建立起联系,并且服务器需要知道这个请求来自哪个用户,于是Cookie技术就出现了。
Cookie
Cookie是HTTP报文的一个请求头,Web应用可以将用户的标识信息或者其他一些信息(用户名等)存储在Cookie中。用户经过验证之后,每次HTTP请求报文中都包含Cookie,这样服务器读取这个Cookie请求头就知道用户是谁了。
Cookie储存在客户端,里面包含了每次请求中都需要传递的信息。
由于Cookie存储在本地,这样就非常的不安全。浏览器在Cookie中填充了一个Session ID之类的字段用来标识请求。
不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。
设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。
存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个Chrome窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。
Session
Session储存在服务器端,里面保存了用户的状态,用户信息以Session的形式存储在服务端。当用户请求到来时,服务端可以把用户的请求和用户的Session对应起来。
工作过程:
服务器在创建Session的同时,会为该Session生成唯一的Session ID,当浏览器再次发送请求的时候,会将这个Session ID带上,服务器接受到请求之后就会依据Session ID找到相应Session,找到Session后,就可以在Session中获取或者添加内容了。而这些内容只会保存在服务器中,发到客户端的只有Session ID,这样相对安全,也节省了网络流量,因为不需要在Cookie中存储大量用户信息。Session的超时也是由服务器来控制。
Session会在浏览器关闭后消失吗?
大部分的Session机制都使用进程中Cookie来保存Session id的,关闭浏览器后这个进程也就自动消失了,进程中的Cookie自然就消失了,那么Session id也跟着消失了,再次连接到服务器时也就无法找到原来的Session了,也就等于Session没用了。
其实服务器是不会知道浏览器关闭了没有(你可以在关闭的时候去通知服务器用Session.invalidate()方法,但一般都不会这样做),所以关闭浏览器时服务器是不会删除Session的,也正是这个原因,服务器会设置一个Session失效时间的,不然服务器早晚会被撑爆的。
等距离上一次使用该Session的时间达到设置的失效时间时,服务器就会认为客户端已停止活动,便会将相应的Session删除。
浏览器与session
1、当在同一个浏览器中同时打开多个标签,发送的请求是同一个session;
2、当使用不同的浏览器时,发送请求是不同的session;
3、当把当前某个浏览器的窗口全关闭,再打开,发起相同的请求时是不同的session。
sessionId的生成过程和过期时间
sessionId是一个会话的key,浏览器第一次访问服务器会在服务器端生成一个session,并且有一个sessionId,并且一般保存在cookie中,当浏览器关闭cookie也就消失了
sessionId 也就消失了。
tomcat生成的sessionId叫做jsessionid; jetty为sessionId。
在Java中,是Web应用程序在调用HttpServletRequest的getSession方法时,由Web容器(比如Tomcat、Jetty、Netty)创建的。
Tomcat的Session管理器提供了多种持久化方案来存储Session,通常会采用高性能的存储方式,比如Redis,并且通过集群部署的方式,防止单点故障,从而提升高可用。同时,Session有过期时间,因此Tomcat会开启后台线程定期的轮询,如果Session过期了就将Session失效。
Session和cookie对比
Cookie 和 Session都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不一样。
Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。
Cookie 存储在客户端中,而Session存储在服务器上,相对来说 Session 安全性更高。如果要在 Cookie 中存储一些敏感信息,不要直接写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。
Cookie 一般用来保存用户信息
在 Cookie 中保存已经登录过得用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了;一般的网站都会有保持登录也就是说下次你再访问网站的时候就不需要重新登录了,这是因为用户登录的时候我们可以存放了一个 Token 在 Cookie 中,下次登录的时候只需要根据 Token 值来查找用户即可(为了安全考虑,重新登录一般要将 Token 重写);登录一次网站后访问网站其他页面不需要重新登录。
Session 主要作用是通过服务端记录用户的状态。
典型的场景是:购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。
HTTPS协议
有的网站使用HTTPS协议。HTTPS (全称:Hyper Text Transfer Protocol over SecureSocket Layer),是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。
HTTPS 在HTTP 的基础下加入SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP 之间)。这个系统提供了身份验证与加密通讯方法。它被广泛用于万维网上安全敏感的通讯,例如交易支付等方面。

HTTPS协议可参考 https://segmentfault.com/a/1190000021494676
关于Socket
Socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层(运输层)复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。
传输层的 TCP/UDP 协议, 由操作系统内核实现。
Tomcat和Jetty作为一个HTTP服务器,主要承担了接受连接、解析请求数据、处理请求和发送响应几个步骤。

socket它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。这一部分工作一般是由Web服务器去进行,常用的Web服务器有Tomcat, Jetty和Netty等。
4、运输层-段(segment)
运输层收取了报文,需要与目的主机建立 TCP 连接【三次握手】,建立连接后最后将 TCP 数据报(TCP 报文)向下传递到网络层。
经过TCP三次握手,客户端A与累行客服务器B建立连接。
运输层将应用层发过来的数据报又一层封装,添加进【源端口号】和【目的端口号】以及相关差错检验字段。
TCP三次握手

第一次握手:建立连接时,客户端A发送syn包(syn=x)到服务器B,并进入SYN_SENT状态,等待服务器B确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
第二次握手:服务器B收到syn包,必须确认客户A的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端A收到服务B的SYN+ACK包,向服务器B发送确认包ACK(ack=y+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
TCP报文格式

可参考 TCP 传输控制协议 http://www.leixingke.com/article/detail/CEAPNm9a
3、网络层-数据包(packet)
网络层拿到TCP数据报并封装成 IP 数据报,即在原 TCP 报文的前提之上添加【源 IP 地址】和【目的 IP 地址】等字段信息。最后将 IP数据报向下传递到数据链路层。
IP协议(网际协议地址)
IP协议提供不可靠、无连接的数据报传送服务,即它对数据进行“尽力传输”,只负责将分组发送到目的主机, 不管传输正确与否,不作验证、不发确认、也不保证IP数据报到达顺序,将纠错重传问题交由传输层来解决。
IP数据报格式如下图所示,它是由IP首部加数据组成的。普通的IP首部长为20个字节(IP首部固定长度20),除非含有选项字段, 但其最大长度不会超过60字节。
IP协议是一种不可靠无连接的包传输,当数据包经过多个网络传输后,可能出现错误、目的主机不响应、包拥塞和包丢失等。 为了处理这些问题,在IP层引入了一个子协议ICMP(Internet Control Message Protocol)。 ICMP数据报有两种形式:差错数据报和查询数据报。ICMP数据报封装在IP数据报里传输。 ICMP报文可以被IP协议层、传输层协议(TCP或UDP)和用户进程使用。ICMP与IP一样,都是不可靠传输,ICMP的信息也可能丢失。 为了防止ICMP信息无限制的连续发送,对ICMP数据报传输中问题不能再使用ICMP传输。 查询报文是成对出现的,它帮助主机或网络管理员从一个路由器或另一个主机得到特定的信息。
可参考
ICMP协议(Internet控制报文协议)
ICMP封装成IP数据,ICMP是不能独立使用的,需要封装成IP数据报。
差错报告报文
IP是不可靠的协议。这就表示IP是不考虑处理检验和差错控制的。ICMP就是为补偿这个缺点而设计的。然而ICMP不能纠正差错; 它只是报告差错。差错纠正留给高层协议去做。
查询报文
除差错报告外,ICMP还能对某此网络问题进行诊断。这是通过使用由4对不同报文组成的查询报文来完成的。 它们分别是: “回送请求和回答”、 “时间戳请求和回答”、 “地址掩码请求和回答”以及 “路由器询问和通告” (最初还定义了信息求和信息回答报文,但已经被废弃)。
可参考
Internet控制报文协议 ICMP http://www.leixingke.com/article/detail/n4PQjrAU
2、数据链路层-数据帧(frame)
数据链路层拿到 IP 数据报,它需要封装成以太网帧才能在网络中传输,也就是它需要目的主机的 Mac 地址,此时我们只知道目的主机的 IP 地址。
所以,链路层有一个 ARP 协议,直接或间接的能够根据目的 IP 地址获得使用该 IP 地址的主机 Mac 地址。
说明:“数据包”是包含在“数据帧”里的。
ARP地址转换协议
ARP报文格式如下:

ARP的运行过程
在因特网中,数据报传递过程中包括如下步骤:
1、发送者知道目标端的IP地址
2、IP要求ARP创建一个ARP请求报文,其中包含了发送方的物理地址、发送方的IP地址和目标端的IP地址。目标的物理地址用0填充。
===========
3、将报文传递到数据链路层,并在该层中用发送方的物理地址作为源地址,用物理广播地址作为目的地址,将其封装在一个帧中。
4、同一链路中的每个主机或路由器都接收到这个帧,因为该帧中包含了一个广播目的地址,所有的站点都对报文进行移交,并将其传递到ARP。除了目标机器以外的所有机器都丢弃该报文。目标机器对IP地址进行识别。
5、目标机器用一个包含其物理地址的ARP响应报文做出响应,并对该报文进行单播。
6、发送方接收到一个响应报文,这样它就知道了目标机器的物理地址。
7、这样就可以将携带目标机器数据的IP数据报封装在一个帧中,并单播到目的地址。
ARP缓存
实际上,在真正的协议实现中,并不是每次发送IP报文前都需要发送ARP请求报文来获取目的MAC地址。在大多数的系统中都存在着一个 ARP缓存表。记录着已经获取的MAC地址和IP地址的映射关系,如下图:
发送IP报文前总是先对ARP缓存表进行查找,看是否目标MAC地址存在于缓存表中,如果存在, 则不需要发送ARP请求报文而直接使用此地址进行IP报文的发送。如果不存在,则发送ARP请求报文,并将结果存于ARP缓存表中供以后使用。
另外,ARP缓存表采用了老化机制,在一段时间内如果表中的某一行没有使用,就会被删除,这样可以大大减少ARP缓存表的长度, 加快查询速度。
ARP本身无法跨跃不同网段,当数据要发往外部网络时,通常是首先使用ARP请求网关路由器的MAC地址,之后将数据发往网关路由器, 由网关路由器进行转发。
同一子网内的ARP应用
不同网段的ARP应用
当然,ARP 协议运行的前提是,目的 IP 地址和当前发送方主机处于同一子网络中。如果不然,发送方将目的 Mac 地址填自己网关路由的 Mac 地址,然后通过物理层发送出去。
网关路由由于具有转发表和路由选择算法,所以它知道目的网络该怎么到达,所以一路转发,最终会发送到目的网络的网关路由上。
最后,目的网络的网关路由同样会经由 ARP 协议,取得目的主机的 Mac 地址,然后广播发送,最后被目的主机接受,目标机器用一个包含其物理地址的ARP响应报文做出响应,并对该报文进行单播。发送方接收到一个响应报文,这样它就知道了目标机器的物理地址。 这样就可以将携带目标机器数据的IP数据报封装在一个帧中,并单播到目的地址。
这样百度的服务器就接受到一个 HTTP 请求,于是它解析这个请求,确定该请求的动作是什么,也就是它需要返回什么东西,并构建响应报文,以同样的路线反向拆解数据从网络到达源主机。
物理层(bit)->数据链路层(freme)->网络层(packet)->运输层(segment)->应用层服务器响应结果(可能是HTML或者图片等)按照HTTP协议格式打包。
浏览器拿到数据包后,以HTTP协议的格式解包,然后解析数据,假设数据是HTML。
浏览器将HTML文件展示在页面上。
关闭浏览器(HTPP客户端),断开TCP连接。
可参考 地址转换协议ARP
http://www.leixingke.com/article/detail/qWZnY38Y
以太网封装过程(动图)
http://www.leixingke.com/article/detail/z6ow7GdS
运输层(段)
TCP或UDP报头|数据
网络层(数据包)
IP报头|TCP报头|数据
数据链路层(数据帧)
以太帧帧头|IP报头|TCP报头|数据
物理层(比特流)
10101110…