作为通信学习的开篇,我们探索的第一阶段是浏览器将数据委托出去的过程。
几个名词的百度百科解释:
服务器
服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。
服务器的构成包括处理器、硬盘、内存、系统总线等,和通用的计算机架构类似,但是由于需要提供高可靠的服务,因此在处理能力、稳定性、可靠性、安全性、可扩展性、可管理性等方面要求较高。
在网络环境下,根据服务器提供的服务类型不同,分为文件服务器、数据库服务器、应用程序服务器、WEB服务器等。
HTTP
超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。
HTML
超文本标记语言,标准通用标记语言下的一个应用。是 网页制作必备的编程语言。
“超文本”就是指页面内可以包含图片、链接,甚至音乐、程序等非文字元素。
超文本标记语言的结构包括“头”部分(英语:Head)、和“主体”部分(英语:Body),其中“头”部提供关于网页的信息,“主体”部分提供网页的具体内容。
URI
在电脑术语中,统一资源标识符(Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串。 该种标识允许用户对任何(包括本地和互联网)的资源通过特定的协议进行交互操作。URI由包括确定语法和相关协议的方案所定义。
Web上可用的每种资源 -HTML文档、图像、视频片段、程序等 - 由一个通用资源标识符(Uniform Resource Identifier, 简称"URI")进行定位。
域名
域名(英语:Domain Name),简称域名、网域,是由一串用点分隔的名字组成的Internet上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。
网域名称系统(DNS,Domain Name System,有时也简称为域名)是因特网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP地址数串。 [1]
我们知道访问Web服务器就是在浏览器中输入相应的网址,那么输入网址后是如何生成HTTP请求消息的呢?
网址,准确来说叫URL(统一资源定位器)。URL中包含服务器的域名和要访问文件的路径名(省略则为默认路径)。 浏览器并不认识URL,需要对URL进行解析。
如百度:https://www.baidu.com/
csdn:https://www.youkuaiyun.com/
中国政府网:http://www.gov.cn/
URL的各种格式:
格式 | 含义 |
---|---|
http: | web服务器 |
ftp: | 下载和上传文件 |
file: | 读取本地文件 |
mailto: | 发送电子邮件 |
news: | 新闻 |
解析完URL后,我们知道访问的目标是哪了,浏览器使用HTTP协议来访问Web服务器,那么HTTP协议是什么样?
- 请求报文格式如下:
请求行 - 通用信息头 - 请求头 - 实体头 - 报文主体
请求行以方法字段开始,后面分别是 URL 字段和 HTTP 协议版本字段,并以 CRLF 结尾。- 应答报文格式如下:
状态行 - 通用信息头 - 响应头 - 实体头 - 报文主体
HTTP的主要方法:
生成HTTP请求消息
对URL解析后,浏览器就确定了Web服务器和文件名,请求消息根据格式进行填写:
请求消息格式:
- 第一行称请求行,通过这一行可以大致了解请求的内容。
<方法><空格><URI><空格><HTTP版本>
- 接下来是消息头,每行包含一个头字段,表示请求的附加信息。
<字段名>:<字段值>
...
...
...
<空行>
<消息体>
- 消息体包含客户端向服务器发送的数据
响应消息格式类似:
- 第一行称为状态行,用来解释状态码的短语(如404 NOT FOUND)
<HTTP版本><空格><URI><空格><响应短语>
- 后面相同:
<字段名>:<字段值>
...
...
...
<空行>
<消息体>
响应消息状态码:
状态码 | 含义 |
---|---|
1** | 告知请求的处理进度和情况 |
2** | 成功 |
3** | 表示需要进一步操作 |
4** | 客户端错误 |
5** | 服务器错误 |
由于每条请求消息只能写一个URI,所以每次只能获取一个文件,如果需要获取多个文件,必须对每个文件单独发送一个请求。
生成HTTP请求消息后,浏览器(应用程序)需要委托操作系统把消息发送到网络中,我们首先需要知道目标地址的IP,通过DNS服务器可以根据输入的域名查询Web服务器的IP地址。
为什么要同时使用IP地址和域名?
- IP地址固定为4个字节(32比特),而域名是几十字节到255字节,显然用IP地址效率更高。
- 然而相对于好记的域名,IP地址不方便人记忆。
DNS(域名服务器)是通过域名查询IP地址(或者通过IP地址查询域名)的一个服务器,它可以完美的实现人和机器双方都不做出让步。
如何确定要寻找的DNS服务器?
DNS服务器数量众多,我们想找出确定的DNS服务器可以通过以下方法:
- 首先,将负责管理下级域的DNS服务器的IP地址注册到它们的上级DNS服务器中。
- 然后上级DNS服务器的IP地址再注册到更上一级的DNS服务器,以此类推。
- 最顶层的域称为根域,分配给根域的IP地址全球只有13个。
- 通过缓存可以加快DNS服务器的响应。
查询到目标IP地址后,委托操作系统的协议栈发送消息。
收发操作大致可以分为4个阶段:
- 创建套接字
- 将管道连接到服务器端的套接字上
- 收发数据
- 断开管道并删除套接字
创建套接字阶段:
客户端创建套接字的操作非常简单,只需要调用Socket库中的socket程序组件就可以了。套接字创建完成后,协议栈会返回一个描述符,应用程序会将收到的描述符放在内存中。应用程序是根据描述符来识别套接字的。
1. 准备:
<描述符> = socket(<使用IPv4>,...);
连接阶段:
接下来,我们要委托协议栈将客户端创建的套接字和服务器的套接字连接起来。应用程序通过调用Socket库中的connect组件完成这一操作。
2. 连接
connect(<描述符>,<服务器的IP地址和端口号>,...);
通信阶段:
3. 发送
write(<描述符>,<发送数据>,<发送数据长度>);
接收
<接收数据长度>=read(<描述符>,<接收缓冲区>,...);
断开操作:
4. 断开
close(<描述符>);
客户端与服务器收发数据的完整情形
应用程序:
---------------------------------------------
1. 准备:
<描述符> = socket(<使用IPv4>,...);
...
2. 连接
connect(<描述符>,<服务器的IP地址和端口号>,...);
...
3. 发送
write(<描述符>,<发送数据>,<发送数据长度>);
...
接收
<接收数据长度>=read(<描述符>,<接收缓冲区>,...);
...
4. 断开
close(<描述符>);
...