最近在看网络编程的一些东西,偶然看到有一篇文章将“在浏览器中输入 www.baidu.com 后,浏览器和服务器之间的通信过程”作为一个举例,想到了一道比较经典的面试题(朋友在面阿里后端一面的时候问过),就是我们在浏览器输入 www.baidu.com 点击enter后,到浏览器显示百度的主页,这个过程到底发生了什么。
ps:笔者也是作为一个学习者的角度来按照自己的理解进行一些解读。
整个的环境就是,我们平时的一个局域网中的一台电脑,来访问百度的主页,主要过程如下:
- 打开浏览器在地址栏输入 www.baidu.com ,说明浏览器想要给百度发送一个网页请求的数据包。
- 浏览器通过DNS域名解析服务器(在本地)将域名解析为对应的IP地址。
- 判断这个ip是不是和本机在同一子网,这里需要用到子网掩码,本机分别将两个ip地址(本机ip和百度ip)做一个and运算,看结果是否是一样,是->局域网内通信,直接tcp连接,不是->跨局域网通信,通过网关进行连接。
- 比较发现不属于同一子网,因此数据包需要通过网关进行转发(即本机将请求转发给网关,网关转发给百度服务器,百度服务器的响应结果返回给网关,网关再转发给本机)。
- 通过ARP协议获得 www.baidu.com 的ip对应的mac地址,通过mac地址和ip地址就确定了要建立通信的对象。
- 网关和百度服务器三次握手建立TCP连接。
- 百度服务器收到请求,返回网页的html。
- 网关将响应结果转发给相应的主机的浏览器。
- 浏览器解析html,请求网页中需要的各种资源。
- 浏览器获得请求的资源,对html进行渲染。
- 显示百度的首页。
大致上是这么个过程。
这里需要解释一下一个问题:
为什么区分私网(局域网)和公网(广域网)以及网关怎么知道将消息转发给哪一台主机?
首先公网IP是有限的,而且是收费的,全球这么多设备要上网,每台设备一个IP肯定是不够的,因此在一个局域网中,可以多个设备共用一个公网IP,每台设备又有一个子网IP。这就相当于,全球每个人需要住一个房子是不够的,我们可以安排一家人住一个房子,每个人住一个房间,他们共享一个家庭住址,每个人又有自己的房间地址。在局域网内通信可以直接使用设备子网IP,因为这个IP是大家都知道的,就像房子中你知道上楼左转是哥哥的房间,右转是姐姐的房间一样,但是不同子网之间是不能使用这个IP的,因为这个左转和右转,仅仅是局限于你们家的房子,别人家的房子构造是不一样的,这时候我们就需要通过网关来进行通信,你可以理解成房子与房子之间的通信,使用住址进行通信,假设只有爸爸知道房子的住址,可以和其他房子进行通信,这样你就可以通过爸爸发消息给你的好朋友小明,(这里的你和小明分别是两个子网中的两台主机,而爸爸相当于网关),这样我们就实现了跨子网(房子)的通信,但是你把消息发给小明,小明给你回信之后,爸爸怎么知道这个信是给谁的呢(也就是网关怎么知道这个消息应该转发给哪一台主机),这里使用端口映射来进行区分。我们只需要将设备ip+端口,映射为网关ip+端口即可。
举例:
设备名 | IP |
---|---|
网关 | 192.168.1.1 |
设备A | 192.168.1.2 |
设备B | 192.168.1.3 |
设备C | 192.168.1.4 |
端口映射后:
源ip:端口 | 映射之后的ip:端口 |
---|---|
A:192.168.1.2:60 | 192.168.1.1:80 |
B:192.168.1.3:60 | 192.168.1.1:90 |
C:192.168.1.4:60 | 192.168.1.1:100 |
这样我们就可以知道,网关80端口来的消息要转发给设备A的60端口,依次类推。也就实现了局域网共用一个公网IP的方式。