理解网络传输(一)
引言
上网如此简单。如果不出所料的话,你已经掌握了如何利用网络来搜索有用的消息了,不然你就看不到这篇精彩的文章了
一般来说,我们想要在网上获取某些信息,只需要在浏览器上敲个网址,不出一会,我们就会收到来自服务器端的信息。假如你未曾学过计算机,你甚至可能不知道服务器的存在。即使你学过计算机,在实际的开发中,你也只需要调用socket接口发起请求,返回响应就可以了
其实我想说,计算机网络被隐藏地太好了,再加上它看不见摸不着,其中的细节很容易被我们所忽略。所以我常常喜欢称网络为熟悉的陌生人
网络如此复杂。假如,我现在问你HTTP、TCP/IP协议是什么?数据在传输的过程中逐步经历了什么?Socket到底是个什么东西?成百上千的信息如何做到有条不紊的传输的?如何做到高效传输?客户端与服务端又是如何配合的?如何搞定网络安全?这些你能回答到几个呢?不要着急,这些问题我会在下面的文章中进行讲解
在讲解之前,我先将网络的传输过程进行细分,大致可以分为三个阶段:客户端请求阶段、网线传输阶段、服务端响应阶段。因为网线传输阶段不是软件开发中的重点,所以我会弱化网线传输的讲解,挑客户端请求阶段和服务器端两点进行详细地说明。那么现在让我们开始吧
浏览器生成消息
这个小节总共有5个看点:
-
浏览器如何解析网址
-
HTTP请求消息长啥样
-
如何通过域名解析获取IP地址
-
全世界DNS是如何配合的
-
委托协议栈发送消息到底是如何完成的
生成HTTP请求消息
访问网站的第一件事情是先在浏览器中输入URL地址。我们就以百度为例 http://www.baidu.com
将网址拆分成两部分,分别是"http://"和"www.baidu.com",这两部分分别代表访问协议和服务器域名。
协议
浏览器除了支持HTTP协议外,还支持“ FTP:”“ FILE:”“ MAILTO:”协议,这部分文字都表示浏览器应使用的访问方法。比如,当访问Web服务器时,应该使用HTTP协议,而访问FTP服务器时则应该使用FTP协议。
网络协议是什么呢?百度百科上的解释是:网络协议是为计算机网络中的数据进行交换而建立的规则、标准或约定的集合。对,没错,就是规则和约定。最简单的协议,比如说,我们过马路要遵守交通规则,否则就有可能发生意外。那为什么要建立交通规则呢?因为我们需要对马路上的车辆和人流(范围)进行管理,使得每个人都能安全的通过马路(目的)。
现在你能说出为什么需要网络协议了吗?是为了能够进行数据交换(目的)而制定的规则,保证(管理)不同类型的数据能够以各种方式准确、高效的传到你的电脑上。
协议的类型有很多:比如,HTTP协议是用于从WWW服务器传输超文本到本地浏览器的传输协议;FTP是网络共享文件的传输协议;MAILTO是一个用于发送邮件的URL协议;FILE协议用于访问本地计算机中的文件的协议
这样说可能还是有点抽象,没关系,那么我们就以HTTP协议为例子,讲解一下协议到底是个什么东西吧。协议总归是有内容的吧,比如交通规则是红灯停与绿灯行,红灯和绿灯是一个信号,用来告诉你的大脑现在该干什么了。不过,HTTP协议的规定可不只两个哦,可以按照实际请求的需要往HTTP请求消息里面添加。
大家应该都知道HTTP请求消息包括请求行、请求头、请求体吧,见下图。
HTTP请求消息.jpg请求头和请求体都是控制信息,请求体才是真正的内容。其实电脑就像我们的大脑,只不过这个大脑把他的智商兑换成了它的处理速度。电脑只做三件事情,分别是:输入,处理请求,响应。我们来分析一下电脑解析下面这段请求消息的过程吧:电脑会先按照换行符把请求消息划分为三个部分,然后依次读取到请求行、请求头的信息,服务程序再根据请求行和请求头的控制信息对请求体进行相应的处理,生成对应的响应信息。总结起来,HTTP请求消息就是我们人为的规定了一些字段,计算机接收到信号之后(红绿灯),按照HTTP协议规定的方式去处理(停、走、发生错误),从而达到传输超文本的目的
请求头.png理解协议是很关键的一环,下面会大量提到协议,所以我尽量通俗的讲解协议,花了很多笔墨,接下来讲一下域名
域名
互联网是一张大网,在互联网上有上亿的计算机通过网络连接,如何确定我要访问的是哪一台计算机?对,你说得没错,是通过IP去找的,所以如何找是通过IP协议规定的。IP协议仅仅是能够帮你定位到这台主机在互联网的位置,如何进行连接就需要使用到TCP协议了。这就是我们常常挂在嘴边的TCP/IP协议了。这里要注意一点的是,TCP是传输层的协议,而IP是网络层的协议,这两个协议是两个层的代表,所以我们常说的TCP/IP协议是一个协议族。
再介绍TCP/IP协议之前,我先简单的引入网络层次结构的概念,见下图:
TCP&IP五层模型.jpg不同的网络层次只负责自己分内的工作,处理完了自己的工作后,就把这个工作交给其他人继续完成。好了,先说到这里,更多的知识我们接下来很快就会讲到,我们回到主线:域名解析与IP
IP写出来是一个数字串,数字的设计是为了让人们更加高效的找到他们要访问的主机。如果要拿什么作类比的话,就像学生的学号,你不可能用名字来识别学校里的每一个学生,所以如果你想快速地找到某个人,那么最高效的方式就是查学号,然后得到这个人的所有信息。
网络中总共有约42亿个地址,合理的分类和规划就显得非常重要。我们国家有14亿人口,你想想看,你的身份证号是如何编码的?有哪几部分组成?像身份证就能唯一表示你这个人。为了方便管理,IP地址被人为地分成了A类地址、B类地址、C类地址,每一个IP又有网路号和主机号构成。像有些大公司里面可能需要一个能够接入很多电脑的IP,那么他就要申请一个A类地址的IP。一个IP最多可以接入16,777,214台电脑(A类地址),最少可以接入254台电脑(C类地址)。
IP地址的分类.jpgIPv4当初设计的时候只是为了实验,只有2^32个地址。但是随着现在PC、网络设备和移动设备越来越多,需要的IP地址也越来越多,所以IPv4的地址资源已经枯竭,而IPv6又没有开始普及,所以只能尽量节省地址。比如定义了私有地址、开发了NAT技术以及子网划分等。
我相信不会有人会去申请不够用的IP,但是会发生申请到的IP存在浪费的情况。比如,这是一个小公司,存在一个公司需要接入的电脑还不足256台的情况。为了有效利用ip地址,这个时候我们就可以根据情况将一个IP划分成几个子网,分配给这个公司的子公司使用。
大致了解了IP的概念,我们开始讲重头戏:域名解析。IP虽然高效,但是带来一个问题,那就是IP太难记了,于是我们就想了一个办法,那就是域名解析。有了域名解析服务之后,我们既可以用域名也可以用IP访问网站了。域名解析的含义就是将域名映射成IP的过程。域名如果不经过转换,是无法直接用于访问的。你可能很好奇吧,好端端的一个域名www.baidu.com是如何变成http://112.80.248.76/的呢?
域名服务器在其中发挥了重要的作用。在浏览器发起请求之前,会先向域名服务器发起请求,返回相应的要访问的服务器的IP地址。有了域名对应的IP地址后,就可以向目标服务器发起请求了。
简单理解就是这么个过程,但我们的目标不仅于此。DNS服务器中的所有信息都是按照域名,分层次保存的。一个层级的部分称为域。以百度为例,www.baidu.com是一个域名,它由三部分组成,以'.'号进行分隔,从右往左分别为一级域名com,二级域名baidu,三级域名www。在一级域名之前有一个根源,根域是最高的域,用一个点来表示,一般可以省略。根域的DNS服务器中保管着com、jp等的DNS服务器的IP信息。根域服务器在全世界上只存在13个。而且根域的地址几乎不发生变化,因此将这些地址保存在所有的DNS服务器中也并不是一件难事
解析的具体过程。首先,将负责管理下级域的DNS服务器的IP地址注册到它们的上级DNS服务器中,然后上级DNS服务器的IP地址再注册到更上一级的DNS服务器中,以此类推。也就是说,负责管理www.baidu.com这个域的DNS服务器的IP地址需要注册到baidu.com域的DNS服务器中,而baidu.com域的DNS服务器的IP地址又需要注册到com域的DNS服务器中。这样,我们就可以通过上级DNS服务器查询出下级DNS服务器的IP地址,也就可以向下级DNS服务器发送查询请求了
用百度举个例子。从你的电脑出发,域名首先会发往离你最近的域名解析服务器,最近的域名解析服务器如果没有找到该域名的缓存,那么该域名服务器就会把域名发给根域服务器。补充一点,根域服务器存在于与任何一台域名服务器上。因为根域服务器只有13个,所以任何一台根域服务器都能轻易存储。最近的根域服务器会返回他管辖的最近的com域服务器的IP。你的电脑收到最近的com域服务器的IP后,会将域名发给最近的com域服务器,com域服务器会返回他管辖的baidu.com域服务器的IP地址。最后,你的电脑继续把域名发给最近的baidu.com域服务器,返回www.baidu.com的域名服务器。你的电脑收到收到这个域名服务器的ip后,判断这就是我想要的域名IP,接着浏览器就会向这个IP地址发送HTTP请求。
域名解析.png域名解析到此结束。接下来,我们将正式向客户端发送消息了。
浏览器委托操作系统发送消息
还记得我们前面说得计算机层级结构吗? HTTP协议与DNS协议都位于应用层。像TCP协议规定了如何可靠的传输、IP协议规定了如何快速地找到目的主机,分别位于传输层与网络层。层次从上而下就好比我们一步一步的解决问题。我们通过使用HTTP协议控制客户端与服务端之间的超文本传输,要传输就要建立可靠连接(TCP),建立连接后就要高效的定位主机(IP),由上而下,分别对应了应用层、传输层、网络层。如果要做个类比的话,应用层之下的层级好比一颗树的树干,应用层好比是树的树枝。树枝向四处发展,每个树枝都有自己独特的地方,但是每个树枝都依靠同样的一根树干去传输养分。这好比应用层的协议,它基于应用层之下的各层,为了实现一个特定应用功能,从而规定和控制信息的传输。像HTTP协议可以控制超文本传输过程、FTP协议可以控制文件的传输过程、MAILTO可以控制邮件传输过程,DNS协议控制域名与IP的传输过程。网络层次中的每一层都依赖下一层,下一层对上一层提供服务,这是层次结构的精髓
我们已经讲了HTTP和DNS这样的应用层了,接下来我们讲TCP的传输层。
在讲之前,我们先把数据包从浏览器到网卡经过的路径先捋一下
- 域名解析流程。对于DNS服务器,我们的计算机上一定有相应的DNS客户端,而相当于DNS客户端的部分称为DNS解析器,或者简称解析器。解析器实际上是一段程序,它包含在操作系统的Socket库中。库就是一堆通用程序组件的集合,其他的应用程序都需要使用其中的组件。Socket库也是一种库,其中包含的程序组件可以让其他的应用程序调用操作系统的网络功能。但我们输入网址,按下回车,浏览器就会调用解析器。响应消息中包含查询到的IP地址,解析器会取出IP 地址,并将其写入浏览器指定的内存地址中。
浏览器内部伪代码如下:
<应用程序名>(<参数>)
{ ....
....
<内存地址> = gethostbyname("www.baidu.com");
....
....
<发送HTTP消息>
....
}
调用解析器时计算机内部的工作流程 .png
-
什么是协议栈。协议栈是操作系统内部的网络控制软件,也叫“协议驱动”“TCP/IP 驱动”等。是真正处理网络收发过程的软件。这是因为和浏览器一样,解析器本身也不具备使用网络收发数据的功能。解析器调用协议栈后,控制流程会再次转移,协议栈会执行发送消息的操作,然后通过网卡将消息发送给DNS服务器。计算机的内部结构就是这样一层一层的。也就是说,很多程序组成不同的层次,彼此之间分工协作。当接到上层委派的操作时,本层的程序并 不会完成所有的工作,而是会完成一部分工作,再将剩下的部分委派到下 层来完成。
-
委托协议栈发送消息。浏览器程序得到IP后就要调用协议栈来收发数据了。要发送给Web服务器的HTTP消息是一种数字信息, 因此也可以说是委托协议 栈来发送数字信息。收发数字信息这一操作不仅限于浏览器,对于各种使用网络的应用程序来说都是共通的。因此,这一操作的过程也不仅适用于 Web,而是适用于任何网络应用程序。收发数据的操作分为若干个阶段,可以大致总结为以下4个:
-
创建套接字(创建套接字阶段)
-
将管道连接到服务器端的套接字上(连接阶段)
-
收发数据(通信阶段)
-
断开管道并删除套接字(断开阶段)
协议栈会调用Socket库中的程序组件去执行相关的数据收发操作。为了显得内容不那么繁杂,关于Socket套接字我会在下一篇文章讲TCP/IP的时候具体讲吧。
-
-
协议栈委托网卡发送数据。协议栈的上半部分有两块,分别是负责用TCP协议收发数据的部分和负责用UDP协议收发数据的部分,它们会接受应用程序的委托执行收发数据的操作。下面一半是用IP协议控制网络包收发操作的部分。在互联网上传送数据时,数据会被切分成一个一个的网络包 ,而将网络包发送给通信对象的操作就是由IP来负责的。此外,IP 中还包括ICMP协议和ARP协议。 ICMP用于告知网络包传送过程中产生的错误以及各种控制消息,ARP用于根据IP地址查询相应的以太网MAC地址(链路层)。 IP下面的网卡驱动程序负责控制网卡硬件,而最下面的网卡则负责完成实际的收发操作,也就是对网线中的信号执行发送和接收的操作。
- 网卡出去进入互联网。因为不是简介的重点,我就讲一下这一步的流程。以家庭上网为例。第一步需要通过PPP协议验证密码。电信号从网卡出去,到达你家里的路由器,路由器通过接入网(如光纤)到达运营商,运营商自动给你的路由器分配一个公网IP和DNS服务器地址;第二步,使用外网IP对数据包进行封装,从而使得数据包能在互联网上传输,其实运营商的网络也是以路由器为核心组成的,运营商之间的相互通信就构成了核心网络。我们的数据包在核心网络里可以被转发到世界上任何一个主机上。于是,你就可以访问世界上任何一台主机了。