读书笔记:网络是怎样连接的(上)

federico-beccari-720173-unsplash.jpg

这本书对网络进行了一个整体,详尽的介绍。看过第一章后就可以知道这是本好书。要仔细读下去。该书内容较多,所以笔记要记概括,简明。作为备忘和标注以及存在网络方便用。不需要将全书内容都仔细记下。允许存疑。

格式备注:


日后有补充和纠错,用红色标注

*号粗体表示扩展和解释。如果没写,用绿色背景。

编写日志中绿色部分是需要随时再补充的。

注:用斜体

尽量不要写太多的注,因为会使文章不清晰凌乱。

*扩展内容四级标题

大标题前空一格

图片要加图例?

三号标题的(*)表示还有多少点是没解释了和懂的


编写日志:


  1. 2018.7.23 :写完一章的笔记。
  2. 2018.8.07 :今天面试回来,考了TCP和UCP的区别,还以为用不上这本书结果用到了。抓紧快看。写到了1.1.6结束
  3. 2018.8.08 :第一章写完。23号那天看错了,写完的不是第一章,是第一小节。修改了格式。
  4. 2018.9.23 :全书看完,整理笔记。写到了2.3.5节

读前需要了解的知识和整体架构:

因为该书的体系结构很强,以网络传输的一环讲起,所以在读书时需要知道网络的整体架构和相关的概念。

网络是怎样链接的_概览.png

第一章 浏览器生成消息


本章有四节,按顺序读也是Web浏览器发送消息给服务器的四个步骤,分别为:

  1. 生成HTTP请求消息
  2. 向DNS服务器查询Web服务器的IP地址
  3. DNS服务器接力
  4. 委托协议栈发送消息

1.1 生成HTTP请求消息(*2)


1.1.1 网址

网址就是用户在浏览器输入的URL(Uniform Resource Loacater统一资源定位符),URL包括域名和访问文件的目录名等等(用户名,密码,服务器端口号)。

不同的访问方法(协议),URL长得都不一样。

URL开头的http:等等是浏览器要使用的访问方法。(但其实大部分是*协议(protocol)类型,如ftp:。但file:这种是不使用网络的,所以成为访问方法更好,但是主要还是各式各样的协议)

1.1.2 解析URL

URL包含着文件的层级目录以及服务器地址。

1.1.3 省略文件名的情况

如www.baidu.com/dir/,/后面并没有写文件名,说明在dir下设置了默认文件。

再如www.baidu.com,没有路径名,说明在根目录下以及设置好了默认文件。

或者:www.baidu.com/dir/xx,xx会被当作文件或者是目录处理,具体看xx倒是是什么。

1.1.4 HTTP基本思路

HTTP协议(Hypertext Transfer Protocol超文本传送协议)定义了客户端和服务器交互的消息内容和传输步骤

所有应用都遵循这个协议吗?HTTP协议到底是什么?

这个图很重要。发送的请求消息包括“对什么”(URL)“怎么做”(方法)。消息中还包括头字段等等,后面会讲到。收到请求消息后服务器做出相应动作并将结果存放到响应消息中然后发出响应。响应消息中有一个状态吗,后面跟着头字段和网页数据。这些后面会细讲。

20180807194856.png

1中请求消息中的方法:

20180807201312.png

*get和post

get方法只能发送几百个字节,超过一定长度必须用post来发送。

关于方法的使用,后面再补充。

1.1.5 生成HTTP请求消息

HTTP消息的格式必须严格规定。

20180807202744.png

使用什么方法,取决于哪种场景。(有很多场景会发送请求消息)

第一行的末尾要写http的版本号。

消息头随着浏览器的版本类型不同而不同

一个http消息的例子:

20180807203151.png

1.1.6 响应消息

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

返回响应消息后,浏览器里就有网页显示了,如果有图片等资源,浏览器显示文字时会搜索的图片标签,在屏幕上留出用来显示图片的空间,然后再次访问 Web 服务器,和获取网页文件时一样获取图片。

每条请求消息只能写一个URL,所以遇到资源会再次请求。三张图片就要另外请求三次。

1.2 向 DNS 服务器查询 Web 服务器的 IP 地址(*5)


生成http消息后,要委托操作系统发送给web服务器。因为浏览器能够解析网址生成http消息,但是不能发送消息。

1.2.1 IP地址的基本知识

发送给服务器消息要查域名对应的ip地址。所以要了解一下ip地址是什么东西。在这之前要了解一下TCP/IP。

TCP/IP结构:

2018-08-08-15-47-42.png

但其实我还是不明白互联网的整个架构,有中心吗?每个国家和国家之间怎么交互?

路由器集线器等第三章有讲解。

还有别的结构吗?

IP地址

2018-08-08-15-53-33.png

IP地址为32比特的数字,按8比特一组分成四组。这组数字无法区分哪个是网络号主机号。因为两部分的结构不是固定,所以需要子网掩码表示结构。

子网掩码

2018-08-08-15-58-14.png

10.11.12.13/255.255.255.0这中有一点长,也可以把 1 的部分的比特数用十进制表示并写在 IP 地址的右侧,如10.11.12.13/24

主机号全0代表子网,1代表广播(像子网所有设备发送包)。

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

TCP/ip网络是通过ip来确定的通信对象的。ip由域名查询出的。为什么要用这种机制(域名查ip)是有道理的。

只用ip太难用,只用域名太没有效率。

当然IP地址也是可以直接代替服务器名(域名?)的,但如果用了虚拟主机就不行了。

1.2.3 Socket 库提供查询 IP 地址的功能

向 DNS(Domian Name System) 服务器发送查询消息,并接收服务器返回的响应消息。所以计算机上一定有相应的 DNS 客户端,DNS 客户端称为 DNS 解析器。

通过 DNS 查询 IP 地址的操作称为域名解析,解析器(resolver)负责执行解析(resolution)操作。

解析器程序在操作系统的Socket库中。

Socket 库是用于调用网络功能的程序组件集合。

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

调用解析器,并输入网址:gethostbyname(“www.lab.glasscom.com”)。这样就会像DNS服务器发送查询消息并返回响应消息。解析器会将响应消息中的IP保存。

1.2.5 解析器的内部原理

HTTP消息是文本编写,DNS消息是二进制的。

解析器不具备收发数据的功能,要委托给协议栈。所以调用了解析器后,解析器要调用协议栈(后面有讲)。协议栈发送消息,通过网卡发送给DNS服务器。

2018-08-08-16-30-07.png

DNS服务器的IP是TCP/IP的设置项目事先设置好的,不需要查询。解析器会根据设置好的地址发送消息。

1.3 全世界 DNS 服务器的大接力


1.3.1 DNS 服务器的基本工作

客户端查询消息包括三种:域名、Class(IN)、记录类型(MX、A等)

根据这三样东西在服务器的数据表的资源记录上查找全匹配的内容返回。

作为A记录在DNS上注册的,都可以作为服务器域名。

邮箱要提供@后的内容。而且在DNS服务器记录中也和A类不同,相应数据还包含了优先级(小数值更优先)和邮件服务器域名(这个域名才有IP)。

2018-08-08-16-48-38.png

 

1.3.2 域名的层次结构

越靠右层级越高。

如:www.lab.glasscom.com “com 事业集团 glasscom 部 lab 科的 www”

一个域名不能拆开存放在多个服务器。

如果想在一个域名下分开两个域名单独管理,比如公司旗下的两个业务,但开头域名肯定要一样,可以使用子域。

互联网中的域名也是通过创建子域来分配给不同国家。

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

通过上级DNS查询下级层层查找。

根域

顶层域的上层还有一个根域,没有名字,通常省略。要是非要写那就是www.xxx.com.(后面加个点),根域的DNS服务器信息保存在所有DNS服务器(保证任何DNS服务器都能找到根域服务器)。

分配给根域服务器的IP只有13个(地址只有13个,但是服务器数量很多)

 

2018-08-08-17-05-36.png

注意图中,每次的返回结果是给最近服务器的,直到找到了IP才返还给客户端。并非每次都返还给客户端。是由最近的DNS服务器来做找到IP这个工作的。

真实情况和图还是有一些差别

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

DNS服务器缓存可以记住之前查过的域名。每次查询可以从缓存的位置向下进行。

“不存在”这种响应也会保存。

缓存具有时效性,并且DNS服务器也会告知客户端响应结果来自缓存还是负责管理域名的DNS服务器。

书上没写,但我的理解是:当解析器查询时,缓存应该存在了最近的DNS服务器中

1.4 委托协议栈发送消息(*1)


1.4.1 数据收发操作概览

HTTP是数字消息,而且要委托协议栈来发送。这个收发数据的操作适用于所有的网络应用程序。收发数据操作也需要Socket库。

概览:

2018-08-08-17-26-10.png

四个步骤:

(1)创建套接字(创建套接字阶段,服务器先创建进入等待状态。)
(2)将管道连接到服务器端的套接字上(连接阶段)
(3)收发数据(通信阶段)
(4)断开管道并删除套接字(断开阶段)

每个阶段都需要Socket库的调用,都是由协议栈执行的。但是为了讲解方便,将协议栈和Socket库合在一起。Socket作为桥梁而存在。

应用程序是无法做这些的,只能委托

1.4.2 创建套接字阶段

2018-08-08-17-45-16.png

描述符用来识别不用的套接字。一个计算机是可以存在多个套接字的,因为肯定会有多个数据的通信操作存在。

描述符是用来给应用程序用的。

1.4.3 连接阶段:把管道接上去

端口号

在上图的第二个步骤,第三个参数,端口号是让通信的另一方识别套接字的机制。和描述符的功能不一样,描述符是用来计算机内部识别套接字的。

端口号的规则是统一的,服务器上的端口号也是根据应用类别事先规定好的。

客户端在创建套接字时,协议栈会为这个套接字随机分配端口号(可以指定)。进行链接操作时,会将这个端口告诉服务器。

端口号还用更多作用,后面会讲到。

连接成功后,协议栈会将对方的地址和端口号等信息保存在套接字中。

1.4.4 通信阶段:传递消息

应用程序无法直接控制套接字,还是要通过 Socket 库委托协议栈来完成操作。

需要调用write组件。如上图。通过描述符指定的套接字找到通信对象并发送数据。结束后向客户端返回消息。

最后用read接收消息到缓冲区。

1.4.5 断开阶段:收发数据结束

HTTP协议规定,Web服务器发送完响应消息后要主动先断开操作。随后客户端断开。

HTTP 协议将 HTML 文档和图片都作为单独的对象来处理。因为重复的链接断开,导致效率很低。后来的1.1中可以在一个连接中收发过个请求和响应。

第二章 用电信号传输TCP/IP数据



2.1 创建套接字

2.1.1 协议栈的内部结构

2018-09-23-11-12-22.png

图中只是总体规则,也有顺序颠倒的时候。

协议栈中TCP和UDP协议是负责收据收发的部分,一般短数据用UDP,长数据用TCP。IP协议负责收发动作,分割网络包,iP协议中还有ICMP和ARP协议。

2.1.2 套接字实体

套接字是一个概念,不存在实体,协议栈内部存放控制信息(IP地址,端口号)的内存空间可以说就是套接字的实体。

协议栈进行操作时需要看这些控制信息。根据控制信息判断下一步动作就是套接字的作用。

windows中可以使用netstat命令查看套接字:

2018-09-23-11-38-59.png

2.1.3 调用socket时的操作

socket像协议栈发送委托,然后协议栈分配套接字的内存空间,写入初始状态控制信息。将套接字的描述符告知给应用程序。当应用像协议栈委托收发数据时就需要提供这个描述符。

为什么存在描述符?

2.2连接服务器

2.2.1 连接的意思

连接实际上就是通信双方交换控制信息并为收发数据开辟临时空间,交换的内容由通信规则确定。

(也可以把连接叫 准备)

2.2.2 负责保存控制信息的头部

控制信息分为两类:一类是客户端和服务器连接,收发,断开操作时交换的控制信息。存在于网络包的开头,称为头部。(以太网和IP协议也有头部,分别叫TCP头部,ip头部,MAC头部)如图:

2018-09-23-12-05-03.png

另一类是控制协议操作的信息,保存在套接字中(也就是保存在内存空间中),协议栈根据这些信息进行操作。无论任何OS,这些信息都是共同的。

(不同的系统实现协议栈的方式不同,所需的内容也不同。但只要按照通信规则把必要信息写入头部就可以通信)

两类信息一类用于发送途中,另一类用于协议栈使用。

2.2.3 连接操作的实际过程

连接操作的第一步是在TCP 模块处创建表示连接控制信息的头部。

通过TCP 头部中的发送方和接收方端口号可以找到要连接的套接字。

头部中的控制位SYN设为1,表示连接。然后TCP模块委托IP模块发送,服务器收到后将ACK设为1,表示已接收,客户端收到数据后也将ACK设置为1并回传服务器。

2.3收发数据

2.3.1 将HTTP请求消息交给协议栈

协议栈并不关心传来的数据内容,也并不是收到数据会马上发送,而是存入内部的缓冲区中。

应用程序交给协议栈发送的数据长度是由应用程序本身来决定的。

一次将多少数据交给协议栈是由应用程序自行决定的,所以协议栈要根据MTU,MSS以及计时器来确定何时发送数据包,避免发的过小或大。当从应用程序收到的数据长度超过或者接近MSS 时再发送出去,就可以避免发送大量小包的问题了。或者通过等待时间来发送数据。但是MSS与等待时间是两个互相冲突的参数,需要按需调整。

MTU:一个网络包的最大长度,以太网中一般为1500 字节

MSS:除去头部之后,一个网络包所能容纳的TCP 数据的最大长度。

2018-09-23-17-30-26.png

(应用程序若指定“不等待填满缓冲区直接发送”,则协议栈就会按照要求直接发送数据)

2.3.2 对较大的数据进行拆分

2018-09-23-18-18-01.png

2.3.3 使用ACK确认网络包已收到

服务器和客户端都需要计算包序号,包序号是随机的。

接收方会将到目前为止接收到的数据长度加起来,计算出一共已经收到了多少个字节,然后将这个数值写入TCP头部的ACK 号中发送给发送方。返回ACK 号时,除了要设置ACK 号的值以外,还需要将控制位中的ACK 比特设为1,这代表ACK 号字段有效。

为了确保服务器和客户端数据收发正常,TCP有如图所示的机制:

2018-09-23-18-29-23.png

如果没有返回对应的ACK号则重新发包。

(ACK号使用过包长算出来的,ACK比特是确定ACK号是否有效的标记)

硬件设备是没有错误补偿机制的,应用程序也一样。但是通过TCP传输可以补偿错误。但TCP在尝试一定次数后还未发出则会结束通讯。

2.3.4 根据网络包平均往返事件调整ACK

错误检测和补偿机制有关键的点:ACK号的等待时间(超时时间),若等待时间过短,重发包后ACK才到,就会发生网络拥堵。TCP通过持续测量ACK返回时间来动态调整等待时间。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注