- url:不止可以以http等开头,也可以以ftp,file等开头,因为浏览器不只有访问web服务器的功能,它还可以用来在ftp服务器上下载和上传文件,同时也具备电子邮件客户端的功能
- 当url并没有指定要访问的文件时,比如http://www.lab.glasscom.com/dir/,则会去访问服务器指定的默认的文件,比如Index.html等
- 客户端请求消息包含的内容包括“对什么”(url)和“做什么操作”(get,post等)两个部分。
- CGI是Web服务器和运行其上的应用程序进行“交流”的一种约定。
- http请求方法:
- 在给web服务器给客户端返回数据时,在开头会有一个状态码,它用来表示操作的执行结果是成功还是发生了错误
- Web服务器的响应消息的格式以及基本思路和请求消息是相同的,差别只在第一行上,在响应消息中,第一行的内容为状态码和响应短语,用来表示请求的执行结果是成功还是出错。
- Ip地址解析
- Ip特殊含义:
- 我们计算机上的dns客户端被称为dns解析器,简析解析器,解析器实际上是一段程序,它包含在操作系统的Socket库中,Socket库是用于调用网络功能的程序组件集合
- 根据域名查询IP地址时,浏览器会使用Socket库中的解析器
- Dns查询是使用udp协议
- Dns收到的查询消息包括三种:
- 域名
- Class:在最早设计DNS方案时,DNS在互联网以外的其他网络中的应用也被考虑到了,而Class就是用来识别网络的信息。不过,如今除了互联网并没有其他的网络了,因此Class的值永远是代表互联网的IN
- 记录类型:表示域名对应何种类型的记录。例如,当类型为A时,表示域名对应的是IP地址;当类型为MX时,表示域名对应的是邮件服务器。对于不同的记录类型,服务器向客户端返回的信息也会不同
- 例如,如果要查询www.lab.glasscom.com这个域名对应的IP地址,客户端会向DNS服务器发送包含以下信息的查询消息。域名=www.lab.glasscom.com;Class = IN;记录类型=A然后,DNS服务器会从已有的记录中查找域名、Class和记录类型全部匹配的记录
- 当记录类型为MX时,DNS服务器会在记录中保存两种信息,分别是邮件服务器的域名和优先级。此外,MX记录的返回消息还包括邮件服务器mail.glasscom.com的IP地址
- 除了A和MX两种类型,还有根据IP地址反查域名的PTR类型,查询域名相关别名的CNAME类型,查询DNS服务器IP地址的NS类型,以及查询域名属性信息的SOA类型等
- 假设一台dns服务器只保存一类域,则客户端查找目标域名对应的Ip方式如下图
- 但是在真实世界中,
- 一台dns管理了多个域信息,在上级域和下级域共享同一台dns服务器时,这种情况下,访问上级dns服务器时就可以向下跳过一级dns服务器,直接返回再下一级dns服务器的相关信息
- 有时候并不需要从最上级的根域开始查找,因为DNS服务器有一个缓存功能,可以记住之前查询过的域名。如果要查询的域名和相关信息已经在缓存中,那么就可以直接返回响应,接下来的查询可以从缓存的位置开始向下进行。相比每次都从根域找起来说,缓存可以减少查询所需的时间。
- 当要查询的域名不存在时,“不存在”这一响应结果也会被缓存。这样,当下次查询这个不存在的域名时,也可以快速响应。
- 这个缓存机制中有一点需要注意,那就是信息被缓存后,原本的注册信息可能会发生改变,这时缓存中的信息就有可能是不正确的。因此,DNS服务器中保存的信息都设置有一个有效期,当缓存中的信息超过有效期后,数据就会从缓存中删除。而且,在对查询进行响应时,DNS服务器也会告知客户端这一响应的结果是来自缓存中还是来自负责管理该域名的DNS服务器。
- 客户端和web服务器的收发:收发数据的操作可以大致总结为以下4个。
- 创建套接字(创建套接字阶段)
- 将管道连接到服务器端的套接字上(连接阶段)
- 收发数据(通信阶段)
- 断开管道并删除套接字(断开阶段)
- 描述符:在套接字创建完成以后,协议栈会返回给应用程序一个描述符,类似于存包的号码牌,用于识别不同的套接字
- 管道连接:我们需要委托协议栈将客户端创建的套接字与服务器那边的套接字连接起来。应用程序通过调用Socket库中的名为connect的程序组件来完成这一操作。这里的要点是当调用connect时,需要指定描述符、服务器IP地址和端口号这3个参数。然后协议栈根据这个描述符来判断到底使用哪一个套接字去和服务器端的套接字进行连接,并执行连接的操作。但是,连接操作的对象是某个具体的套接字,因此必须要识别到具体的套接字才行,而仅凭IP地址是无法做到这一点的。所以需要端口号。
- IP地址和端口号:客户端和服务器之间用来识别对方套接字的机制
- 收发消息:应用层程序通过调用Socket库的write和read组件去委托协议栈接收消息
- 断开阶段:调用Socket库的close程序组件进入断开阶段。最终,连接在套接字之间的管道会被断开,套接字本身也会被删除。Web使用的HTTP协议规定,当Web服务器发送完响应消息之后,应该主动执行断开操作,因此Web服务器会首先调用close来断开连接。断开操作传达到客户端之后,客户端的套接字也会进入断开阶段。接下来,当浏览器调用read执行接收数据操作时,read会告知浏览器收发数据操作已结束,连接已经断开。浏览器得知后,也会调用close进入断开阶段。
- 但是如果浏览器想和服务器持续进行消息传送,对于同一台服务器来说,重复连接和断开显然是效率很低的,因此后来人们又设计出了能够在一次连接中收发多个请求和响应的方法。在HTTP版本1.1中就可以使用这种方法,在这种情况下,当所有数据都请求完成后,浏览器会主动触发断开连接的操作。