本章是‘网络是怎么连接的--读后感’第一章
前言
本章是系列博客的第一章;首先讲浏览器在整个web通信过程中做了哪些事,在对单独实现的需求进行详细讲解,最后有个总结环节
实现需求
- http请求生成通信数据源
- 连接服务器前,先通过dns解析器获取web服务器的地址
- dns服务器扩展,世界dns服务器大接力
- 终端通过委托协议栈发送消息
正文
要通过浏览器访问网站首先需要通过地址栏输入网址,并发起请求;这一步都做了啥?
主要是通过http请求生成通信数据源;
我们一般访问网站是通过输入网址来实现的;网址实例如下:
https://www.baidu.com/search/error.html;输入网址后浏览器首先做的就是解析网址从而生成请求;因此我们首先需要对url有个认识.
上行的url中:https(超文本传输协议)表名访问数据源的机制,也就是浏览器应该使用的访问方法;如果访问web服务器的时候应该使用http/https;访问邮件服务器则使用mailto方法等;之所以要指明协议是因为浏览器除了网站还有其他功能不同的功能需要通过不同的通信协议来实现,而且不同的协议对地址的格式通信要求是不一样的,这样通过不同的协议就能实现不同的功能且不会乱。
url中://表明后面接的字符串是服务器名称。
url中:www.baidu.com是服务器名称;这样说不够确切,确切的应该是www是主机名即服务器名,baidu是一级域名,com是顶级域名。
url中:服务器名称后其实是省略了端口名;结构类似:8080;端口在通信过程中主要用来定位通信的发起应用的。
url中:/search/error.html这一部分表示请求的资源的路径名,error.html就是页面最后展示的文件名称
需要注意这种:https://www.baidu.com/,/代表访问服务器最上层目录,后面没有跟具体的文件名,代表浏览器展示的页面是这个目录中的默认文件。
因此通过解析url浏览器就能知道该访问web服务器的哪个文件;但是该以什么方式来访问呢;这就需要通过http协议的方法来实现。
http/https协议常用的方法有get,post方法;除了这些还有put,delete,head,options,trace,connect方法
get方法:获取url的指定信息,可以理解为查服务器里的信息http://www.ruanyifeng.com/blog/2016/06/dns.html如页面使用get方法来查dns.html这个文件除了查一个文件还可以通过https://www.baidu.com/s?wd=苹果;这种方式来查具体的参数,这种通过将查的参数传入服务器中的cgi程序做为程序输入数据来实现查询;
post方法:客户端/浏览器向服务器发送请求时用的协议,如登陆时输入账号密码登陆即通过post把账号密码发给服务器了,可以理解为提交;
put方法:替换服务器上指定文件;文件不存在创建文件;
delete方法:删除服务器指定文件;
head方法:和get方法类似;它只查询消息头;
option方法:用于通知和查询通信选项;
http请求的结构,一般是这样的:请求行+消息头+消息体
general:含请求行的数据;通过这大致可以了解请求的内容
request headers:消息头,每行一个头信息,用来表示请求的附加信息
message body:包含客户端向服务器发送的数据;如登陆时通过http协议的post方法发送的账号密码
我们向服务器发送请求之后,服务器也会做出回应,即响应,响应的一般结构如下:状态行+消息头+消息体
状态行:general中的status code 表明响应的状态此时是200表明响应正常;
响应的消息头:response headers;包含各种头字段;
响应的消息体:服务器返回的数据;
消息头补充;消息头包含请求或响应的各种头字段;用来表示附加信息。一般包含:
date字段 请求和响应生成日期
pragma 数据是否允许缓存
cache-control 控制缓存的信息。。。很多不一一说明;具体谷歌。
通过http的get/post方法发送请求;请求发送后会收到服务器的响应;响应一般包含状态行,消息头,消息体;消息头和消息体和请求结构类似不在说明
状态行:状态行里含有状态码来表明响应的状态,一般有这几类:‘1xx(1开头的告知请求处理进度和情况);2xx(2开头表明成功);3xx(3表明需要更进一步操作);4xx(4开头表明客户端错误);5xx(5开头表明服务端错误)’
通过上面讲了传输的数据源http请求;需要注意一个http请求中只有一个url,因此只能请求一个对象;如果有多个对象时就需要多个url,多个请求。
生成http请求后就需要委托操作系统将请求传输到服务器;这里注意http请求本身是不传输数据的;传输是通过其他协议栈来实现的;传输到服务器需要通过IP地址来确定服务器;但浏览器输入的是url;因此需要解析url获得服务器IP地址;通过dns解析器即可实现
dns解析器实际是运行在操作系统socket库中的一段程序可以理解为包;通过在编写程序时调用这个解析器的函数即可发起域名查询;通常dns查IP前需要配置解析器响应服务器的IP地址;就是配置tcp/ip协议时配的dns的地址
因此我们通过操作系统中的socket库中的解析器向解析器服务器发起指定请求;来查询指定url的IP;dns服务器中的记录可以理解为表,结构如下:
表结构说明:
class代表类型:IN参数代表互联网类型;
记录类型:A代表的是web服务器;MX代表的是邮件服务器;因此通过url的协议可以确定查的是A;
域名和IP;通过域名即可查到映射的IP;
补充说明可以看到在响应数据里还包含一个域名;这是由dns服务器的分层机制决定的;由于网络中url和IP太多了;一台服务器根本无法完成所有域名解析的需求;因此采用分层结构来提升效率:
举例解析①http://map.baidu.com这个域名;根据电脑配置的域名服务器的地址8.8.8.8首先访问这个域名服务器;这个域名服务器被称为根域也就是最顶层的域名服务器;在他的表的响应数据里面会含有顶级域名如.com,.cn,jp等的地址;解析①这个地址由于顶级域名是.com则根据表里面.com地址接着向。.com域名服务器发起请求,由于在.com中检测到解析的下一级域名是baidu.com,而.com域名服务器里有包含baidu.com域名服务器的地址,因此根据这个地址在发起请求,一直持续,直到最后向map.baidu.com域名服务器发起请求;通过这个服务器响应对应域名的IP;就完成了解析;
这里需要注意的是;域名解析服务器响应数据里面只包含下一级域名的地址;因此要向当前域名解析服务器发起请求必须先向他的上一级域名服务器发起请求;来获取当前域名服务器的地址才能进行请求;同时还需要注意;跟域名是在电脑上配置好的,写入了操作系统的配置文件;因此根域名服务器我们一定是能访问的。
通过域名解析获取到了服务器的IP;我们就可以向服务器发起请求了;发起请求需要通过委托操作系统的协议栈来实现;我们一般用的协议栈是socket库中的tcp/ip协议栈来实现的;这个协议栈也可以理解成操作系统库里面的子程序;通过这个协议栈4步操作完成和服务器的通信:这里不考虑路由器等网络设备
1、实现终端和服务器建立连接,首先需要在两边建立套接字作为入口和出口;服务器的套接字是服务器启动的时候就生成了的。客户端的套接字通过操作系统socket库中的建立套接字的子程序实现的;在建立应用的套接字的时候还会生成应用的描叙字,通过调用应用的描叙字即可调用其套接字
2、建立套接字之后,通过操作系统socekt库的connect程序来实现客户端套接字和服务器套接字的连接;连接成功建立了通信的管道;注意connect方法需要传ip,描叙字,端口参数,IP其实是用来定位终端或者说是网卡的,描叙符是这个终端上应用程序用来定位套接字,端口是客户端和服务器用来定位对方的套接字的;这样才能建立程序,客户端套接字,服务器套接字,服务器这个完整的连接
3、通信,传递消息;这一步同样需要操作系统的socket库中的write程序来实现;输入url生成http请求消息存入内存中后,通过write方法讲内存中的数据写入套接字;这样通过套接字就能讲数据传到服务器了;同样服务器响应的数据通过socket库的read方法读出到内存中,由于这个操作都是在应用程序的内存中操作的,因此也就讲数据传给了应用程序。
4、断开连接,可以是服务器/客户端任意一个先段,http1.1中是服务器在完成响应后使用操作系统的close方法断了连接,这个断开连接消息传到客户端电脑的套接字时,套接字也会跟着断开,后面浏览器通过read接收数据时发现套接字断开后也会调用close方法断开套接字
如上就完成了一次通信;注意这四部都是在操作系统的tcp/ip协议栈控制完成的;第4步是断开,实际有些通信是一直建立管道连接的。同时注意套接字不是应用程序,这是两个对象,应用程序是没法直接和服务器建立连接的