《网络是怎样连接的》第一章 Web浏览器

1.1 生成HTTP请求消息

1.1.1 网址 = URL

URL(统一资源定位符):网址,准确的叫URL,实际上就是以 http:// 开头的的一串东西,但实际上除了http外,网址还可以是其它一些文字的开头,例如,“ftp:”,“file”,"mailto"等

之所以有各种各样的URL,是因为尽管我们通常使用浏览器来访问Web服务器的,但浏览器并不只有这一个功能,它也可以用来在FTP服务器上下载和上传文件,同时也具备电子邮件和客户端的功能,可以说,浏览器是一个具备多种客户端功能的综合性客户端软件。而各种不同的URL就是用来干这个的,比如访问Web服务器时用"http:",而访问FTP服务器时用"ftp:"

当访问Web服务器时应该使用HTTP协议(超文本传送协议),而访问FTP服务器时应该使用FTP协议

URL的各种格式:
在这里插入图片描述

1.1.2 浏览器要先解析URL

浏览器要做的第一个工作就是对URL进行解析,从而生成发送给Web服务器的请求消息,在对URL进行解析时,先将其中的元素拆分出来,通过拆分出来的这些元素,就能明白URL代表的含义

如:http://www.lab.glasscom.com/dir/file1.html 对该URL的理解,表示要访问www.lab.glasscom.com这个Web服务器上路径名为/dir/file1.html的文件,也就是位于/dir/目录下的file1.html这个文件

1.1.3 省略文件名的情况

如:http://www.lab.glasscom.com/dir/ 以" / "结尾代表/dir/后面本来应该有的文件名被省略了,但这种省略是允许的。没有文件名的情况下,服务器上会事先设置好文件名省略时要访问的默认文件名。这个设置会根据服务器不同而不同,大多数情况下是index.html 或者 default.html 之类的文件名

1.1.4 HTTP的基本思路

在这里插入图片描述

解析完URL后,我们就知道应该要访问的目标在哪里了,接下来浏览器会使用HTTP协议来访问Web服务器

HTTP协议定义了客户端和服务器之间交互的消息内容和步骤,客户端会向服务器发送请求消息。请求消息中包含的内容是 ‘对什么’ 和 ‘进行什么操作’两个部分。

其中相当于 ‘对什么’的部分称为 URI(统一资源标识符)即访问对象。一般来说,URI的内容是一个存放网页数据的文件名或者一个CGI程序的文件名(对Web服务器程序调用其它程序的规则所做的定义就是CGI,按照CGI规范来工作的程序称为CGI程序)

进行怎样的操作’这部分被称为方法,方法表示需要让Web服务器完成怎样的工作,其中典型例子包括读取URI表示的数据,将客户端输入的数据发送给URI表示的程序等

HTTP的主要方法
GET:获取URI指定的信息。如果URI指定的是文件,则返回文件的内容,如果URI指定的是CGI程序,则返回该程序的输出数据
POST:从客户端向服务器发送数据,一般用于发送表单(网页中的文本框等能输入数据的部分)中填写的数据
还有PUT,DELETE等方法,使用PUT,DELETE方法,可以从客户端修改或删除Web服务器上的文件

收到请求消息后,Web服务器会对其中的内容进行解析,通过URI和方法来判断‘对什么’及‘进行怎样的操作’,并根据这些要求完成自己的工作,将结果存放在响应消息中。在响应消息的开头有一个状态码,它表示操作的执行结果是否成功或出现错误。当访问Web服务器时,遇到找不到的文件就会显示 404 Not Found 的错误信息,这就是状态码。状态码后面就是头字段和网页数据。响应消息会被发送回客户端,客户端收到后,浏览器会从消息中读取所需的数据并显示在屏幕上,到这里,HTTP的整个工作就完成了

1.1.5 生成HTTP请求消息

在这里插入图片描述

对URL进行解析后,浏览器确认了Web服务器和文件名,接下来就是根据这些信息生成HTTP请求消息。请求消息的第一行称为请求行,这里可以告诉Web服务器它应该进行什么操作。请求行中选择哪种方法根据场景来决定,比如在地址栏中输入网址显示网页和点击超链接,使用的是GET方法,而如果是表单,在HTML源代码中会在表单的属性中指定使用哪种方法来发送请求,可能是GET也可能是POST

1.1.6 发送请求后会收到响应

在这里插入图片描述

在响应消息中,第一行的内容为状态码和响应短语,用来表示请求的执行结果是成功还是出错。状态码和响应短语表示的内容一致,但它们的用途不同。状态码是一个数字,它用来向程序告知执行的结果,相应的,响应短语则是一段文字,用来向人们告知执行的结果

返回响应消息后,浏览器会将数据提取出来并显示在屏幕上,我们就可以看到网页的样子了。如果网页的内容只有文字,那么到这里就全部处理完毕了,但如果网页中还包括图片等资源,会在网页中的相应位置嵌入表示图片文件的标签(编写网页所使用的HTML语言中规定的控制信息)的控制信息。浏览器会在显示文字时搜索相应的标签,当遇到图片相关的标签时,会在屏幕上留出来显示图片的空间,然后再次访问Web服务器,按照标签中指定的文件名向Web服务器请求获取相应的图片并显示

每条请求消息只能写一个URL,所以每次只能获取一个文件,如果需要获取多个文件,必须对每个文件单独发送1条请求,比如一个网页中有3张图片,那么获取网页加上获取图片,共需要向Web服务器发送4条请求

1.2 使用DNS查询Web服务器的IP地址

1.2.1 IP地址的基本知识

生成HTTP消息之后,接下来我们需要委托操作系统将消息发送给Web服务器,尽管浏览器能解析网址并生成HTTP消息,但它本身并不具备将消息发送到网络中的功能。执行这个操作时,需要查询网址中服务器域名的IP地址。在委托操作系统发送消息时,必须提供的不是服务器域名,而是它的IP地址

互联网和公司内部的局域网都是基于TCP/IP的思路来设计的,由一些小的子网通过路由器连接起来组成一个大网络。在网络中,所有的设备会被分配一个地址,这个地址类似 xx号xx室,其中 ‘号’ 对应的是分配给整个子网的,‘号’ 对应的号码称为网络号。‘室’ 对应的号码称为主机号,整体称为IP地址。通过IP地址可以得到访问对象服务器的位置,从而将消息发送到服务器

消息传送的过程大概为,发送者发出的消息首先经过子网中的集线器,转发到距离发送者最近的路由器上,接下来,路由器会根据消息的目的地判断下一个路由器的位置,然后将消息发送到下一个路由器,这样的过程不断重复,最终消息被转发到了目的地

IP的基本思路:
在这里插入图片描述

实际的IP地址是一串32比特的数字,按8比特为一组分为4组,用十进制表示,每组间用圆点隔开。仅凭这一串数字无法区分网络号和主机号,需要使用子网掩码来明确IP地址内部结构

IP地址的主机号全为0表示整个子网,全为1表示向子网上所有设备发送包/分组,即广播

1.2.2 域名和IP地址并用的理由

委托操作系统发消息时,必须先查询好对方的IP地址。实际上,如果使用IP地址来代替服务器名称也是能够正常工作的,然而,同记住一个陌生的电话号码一样,记住一串数字组成的IP地址也是很困难的

那么如果不要IP地址,直接使用名称来确定通信对象不就好了吗?这并不是一个好主意,互联网中存在无数的路由器,它们之间互相配合,根据IP地址来判断将数据传输到什么地方。IP地址的长度为4字节,而域名最短也要几十个字节,最长可以达到255字节。如果使用域名作为通信对象,那么这将极大的增大路由器的负担,传输数据也会花费更多的时间

让人来确认记住名称,让路由器来使用IP地址,为了填补两者间障碍,需要一个机制能够通过名称来查询IP地址,或通过IP地址查询名称,这个机制就是DNS 域名服务系统

1.2.3 Socket库查询IP地址的功能

查询IP地址的方法很简单,只要询问最近的DNS服务器www.xxxx的IP地址是什么即可。向DNS服务器发出查询,也就是对DNS服务器发出查询消息,并接收服务器返回的响应消息。

对于DNS服务器,我们的计算机上有相应的DNS客户端,而相当于DNS客户端的部分称为解析器。解析器实际上是一段程序,包含在操作系统的Socket库中。

库是一段通用程序组件的集合,其它的应用程序都需要使用其中的组件。库有很多好处,首先,使用现成的组件搭建应用程序可以节省编程工作量。其次,多个程序使用相同的组件可以实现程序的标准化。Socket库也是一种库,其中包含的组件可以让其它应用程序调用操作系统的网络功能,而解析器就是这个库种的其中一种程序组件

1.2.4 通过解析器向DNS服务器发出查询

Socket库中的程序都是标准组件,只要从应用程序中进行调用即可,在编写浏览器等应用时,在Web服务器的域名前加上解析器的名“gethostbyname”就完成了对解析器的调用

调用解析器后,解析器会向DNS服务器发送查询消息,然后DNS服务器会返回响应消息。响应消息中包含查询到的IP地址,解析器会取出IP地址,将其写入浏览器指定的内存地址中

结构这些后,就完成了IP地址的查询,接下来,浏览器在向Web服务器发送消息时,只要从该内存地址中取出IP地址,并将它与HTTP请求消息一起交给操作系统就可以了

1.2.5 解析器的内部原理

浏览器调用解析器时,程序的流程控制会转移到解析器内部,解析器会生成要发送给DNS服务器的查询消息,这个过程与浏览器要发送给Web服务器的HTTP请求消息的过程类似。解析器会根据DNS的规格,发送一条请求得知目的域名的IP地址的消息,将它发给DNS服务器,发送这个过程仍然是交给操作系统来执行

向DNS服务器发送消息时,也需要知道DNS服务器的IP地址,只不过这个IP地址是作为TCP/IP的一个设置项目事先设置好的,不需要再查询

1.3 全世界DNS服务器的接力

1.3.1 DNS服务器的基本工作

DNS服务器的基本工作就是根据需要查询的域名和记录类型查找相关记录,并向客户端返回响应消息

来自客户端的查询消息包含3个信息,1,域名即服务器,邮件服务器的名称,2,Class,Class是用来识别网络的信息,不过现在只有互联网,所以Class的值永远为IN,3,记录类型,表示域名对应何种类型的记录,如记录类型为A时,代表域名对应的是IP地址,记录类型为MX时,表示域名对应的是邮件服务器

除了A和MX外,实际上还有很多其它的类型,如根据IP地址反查域名的PTR类型,查询DNS服务器IP地址的NS类型等

DNS服务器事先保存了这3种信息对应的记录数据,DNS服务器根据这些记录查找符合查询请求的内容并对客户端作出响应

1.3.2 域名的层次结构

像公司内部网络这样的Web和邮件服务器数量有限的环境中,所有的信息保存在一台DNS服务器里,这是可行的。但是互联网中存在不计其数的服务器,一台DNS是远不够的,需要将信息分布保存在多台DNS服务器中,这些DNS服务器相互接力配合,从而查找到要查询的信息

DNS服务器中的所有信息都是按照域名以分层次的结构来保存的,类似于公司中的集团,部门,科室这样的结构。DNS中的域名都是用句点来分隔的,如www.lab.glasscom.com,句点代表不同层次之间的界限,越靠右的位置表示其层级越高

这种具有层级的域名信息会注册到DNS服务器中,从而每个域都是作为一个整体处理,也可以在域的下面创建下级域,然后将其分配给各个公司,如www.nikkeibp.co.jp,最上层的jp代表给日本这个国家的域,下一层的co代表日本国内公司,再下层的nikkeibp就是分配给某个公司的域,最下层的www就是服务器的名称

1.3.3 寻找相应的DNS服务器并获取IP地址

查找到DNS服务器中存放的信息,关键在于我们要访问的Web服务器的信息归哪一台DNS服务器管。互联网中有数万台DNS服务器,不可能一台一台去查找。首先将负责管理下级域的DNS服务器的IP地址注册到它们的上级DNS服务器中,然后上级DNS服务器的IP地址再注册到更上一级的DNS服务器中
在这里插入图片描述
再互联网中,com和jp上面还有一层域,称为根域,根域一般被省略。根域的DNS服务器中保管着com,jp等DNS服务器的信息,由于上级DNS服务器保管着所有下级DNS服务器的信息,所以可以从根域开始一路向下顺藤摸瓜的找到任意一个域的DNS服务器。查询的过程大致为,从下向上问,从上向下查

1.3.4 通过缓存加快DNS服务器的响应

在真实的互联网中,一台DNS服务器可以管理多个域的信息,上级域和下级域可能共享同一个DNS服务器,这种情况下,访问上级DNS服务器就可以向下跳过一级DNS服务器

有时候也不需要从最上级的根域开始向下查,因为DNS服务器有一个缓存的功能,可以记住之前查询的域名,如果要查询的域名及相关信息已经在缓存中,那么可以直接返回响应

DNS服务器中的信息都会有一个有效期,当缓存中的信息超过有效期后,数据就会从缓存中删除,而且,在对查询进行响应时,DNS服务器也会告知客户端这一响应的结果是来自缓存还是来自负责管理该域的DNS服务器

1.4 委托协议栈发送消息

1.4.1 数据收发操作概述

知道了IP地址后,就可以委托操作系统内部的协议栈向这个目标IP地址,即我们要访问的Web服务器发送消息。要发送给Web服务器的HTTP消息是一种数字信息,因此可以说委托协议栈来发送数字信息。收发数字信息这一操作不仅局限于浏览器,对使用网络的应用程序来说都是共通的

和向DNS服务器查询IP地址一样,这里也需要Socket库中的程序组件,不过,查询IP地址只需要一个程序组件就可以,而这里需要按照指定的顺序调用多个程序组件

简单来说,收发数据的两台计算机之间建立了一条连接通道,数据沿着通道流动,最后到达目的地,数据的流动是双向的
在这里插入图片描述
在进行收发数据操作之前,双方需要建立起这条通信管道,建立管道的关键在于管道两端的数据出入口,这些出入口称为套接字。我们需要先创建套接字,然后再将管道连接起来。当数据通过管道全部发送完毕后,连接的管道会被断开,管道在连接时由客户端发起,但在断开时可以由客户端或服务器任意一方发起,断开后,套接字删除,通信结束

收发数据可分为4个步骤:
1,创建套接字(创建套接字阶段)
2,将管道连接到服务器的套接字上(连接阶段)
3,收发数据(通信阶段)
4,断开管道并删除套接字(断开阶段)

1.4.2 创建套接字阶段

客户端创建套接字的操作过程非常简单,只要调用Socket库中的socket程序组件即可,调用socket后,程序流会转移到socket内部并执行创建套接字的操作,套接字创建完成后,协议栈会返回一个描述符,应用程序将描述符放在内存中,描述符是用来实别不同的套接字的

由于同一台计算机上可能同时存在多个套接字,在这样的情况下,需要一种方法找出某个特定的套接字,这种方法就是描述符,类似于在酒店取行李时,给工作人员一个号码牌,就可以取回自己的行李。只要出示描述符,协议栈就能够判断我们希望用哪一个套接字来连接或收发数据

1.4.3 连接阶段

应用程序通过调用Socket库中的conne的程序组件来将客户端创建的套接字与服务器套接字连接起来,当调用connect时,需要指定描述符服务器IP地址端口号

第一个参数,即描述符,connect会将应用程序指定的描述符告知协议栈,然后协议栈根据这个描述符来判断到底用哪一个套接字去和服务器端的套接字进行连接
第二个参数,即服务器IP地址,双方必须知道对方的IP地址并告知协议栈
第三个参数,即端口号,仅用IP地址只能找到互联网中某台指定的主机,在进行连接时,还需要识别该主机上的套接字

服务器上使用的端口号是根据应用的种类事先规定好的,比如Web是80号端口,电子邮件是25号端口,只要指定了事先规定的端口号,就可以连接到服务器程序的套接字。而客户端创建套接字时,协议栈会为这个套接字随便分配一个端口号,连接时将这个端口号告知给服务器

1.4.4 通信阶段

应用程序无法直接控制套接字,需要Socket库委托协议栈完成这个操作,使用write这个程序组件,应用程序首先在内存中准备好要发送的数据,根据用户输入的网址生成的HTTP请求消息就是要发送的数据。接下来当调用write时,需要指定描述符和发送数据,然后协议栈就会将发送数据发送到服务器,服务器执行接收操作,解析收到的数据内容并执行相应的操作,向客户端返回响应消息

当消息返回后,需要执行的是接收消息的操作。接收消息通过调用Socket库中的read程序组件委托协议栈完成,当服务器返回接收消息时,read会负责将接收到的响应消息存放到接收缓存区中,当消息被放到接收缓存区时,就相当于已经转交给了应用程序

1.4.5 断开阶段

在完成收发数据后,要调用Socket库中的close程序组件进入断开阶段,最终,套接字间通道被断开,套接字也会被删除。Web使用的HTTP协议规定,当Web服务器发送完响应消息后,应当主动断开操作,因此Web服务器会先调用close断开连接。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值