以下内容主要来自于《网络是怎样连接的》、《计算机网络自顶向下方法》、猿人谷:面试官,不要再问我三次握手和四次挥手等网络博文,在此记录一下学习笔记。
一、网络分层体系结构
计算机网络设计者以分层方式组织协议以及实现这些协议的网络硬件。每一层会向它的上一层提供服务。各层的所有协议被称为协议栈。
因特网的协议栈由5个层次组成:物理层、数据链路层、网络层、运输层、应用层。
应用层:网络应用程序及他们的应用层协议存留的地方。
运输层:在应用程序端点之间传送应用层报文。
网络层:负责将数据报的网络层分组从一台主机移动到另一台主机。
数据链路层:通过源和目的地之间的一系列路由器路由数据报。
物理层:将整个帧从一个网络元素移动到邻近的网络元素(透明地传播比特流)。
OSI(开发系统互连)模型:物理层、数据链路层、网络层、运输层、会话层、表示层、应用层
表示层:使通信的应用程序能够解释交换数据的含义。
会话层:提供了数据交换的定界和同步功能。
二、应用层
HTTP协议
URI:统一资源标识符,用来标识抽象或物理资源的一个紧凑字符串。
URL:统一资源定位符,一种定位资源的主要访问机制的字符串。
URN:统一资源名称,通过特定命名空间中的唯一名称或ID来标识资源。
URI和URN是URL的一个子集。个人的身份证号就是URN,个人的家庭地址就是URL。
Web页面:由对象组成,一个对象只是一个文件,如一个HTML文件、一个JPEG图形、一个Java小程序或一个视频片段等,可通过一个URL地址寻址。每个URL地址由两部分组成:存放对象的服务器主机名和对象的路径名。如URL地址http://www.someSchool.edu/someDepartment/picture.gif,其中,www.someSchool.edu是主机名,/someDepartment/picture.gif是路径名。
Web应用层协议是HTTP(超文本传输协议)。HTTP定义了Web客户向Web服务器请求Web页面的方式,以及服务器向客户传送Web页面的方式。当用户请求一个Web页面时,浏览器向服务器指定端口(默认端口为80)发出对该页面所包含对象的HTTP请求报文,服务器接收到请求并用包含这些对象的HTTP响应报文进行响应。
HTTP使用TCP作为它的支撑运输协议。HTTP客户首先发起一个与服务器的TCP连接。一旦连接建立,该浏览器和服务器进程就可以通过套接字接口访问TCP。客户向它的套接字接口发送HTTP请求并向它的套接字接口接收HTTP响应报文。服务器从它的套接字接口接收HTTP请求报文和向它的套接字接口发送HTTP响应报文。
HTPP是无状态协议,服务器不保存关于客户的任何信息。
非持续连接和持续连接
非持续连接:每个请求/响应对是经一个单独的TCP连接发送。
持续连接:所有的请求及其响应经相同的TCP连接发送(HTTP1.1)。
HTTP默认使用持续连接。非持续连接的缺点:(1)必须为每一个请求的对象建立和维护一个全新的连接。(2)每个对象经手两倍往返时间的交付时延。
HTTP主要方法
HTTP请求报文
典型HTTP请求报文:
GET /somedir/page.html HTTP/1.1
Host:www.someschool.edu
Connection:close
User-agent:Mozilla/5.0
Accept-language:fr
User-agent:用来指明用户代理,即向服务器发送请求的浏览器的类型。
HTTP响应报文
典型HTTP响应报文:
HTTP/1.1 200 OK
Connection:close
Date: Tue, 18 Aug 2019 15:44:04 GMT
Server:Apache/2.2.3 (CentOS)
Last-Modified:Tue, 18 Aug 2019 15:11:03 GMT
Content-Length:6821
Content-Type:text/html
(data data data)
Date:服务器产生并发送该响应报文的日期和时间。
Server:该报文是由一台Apache Web服务器产生的。
Last-Modified:对象创建或者最后修改的日期和时间。
Content-Length:被发送对象中的字节数。
Content-Type:指示消息体中的对象是HTML文本。
常见的状态码
200 OK:请求成功,信息在返回的响应报文中。
301 Moved Permanently:请求的对象已经被永久转移,新的URL定义在响应报文的Location:消息头中。客户软件将自动获取新的URL。
400 Bad Request:一个通用差错代码,指示该请求不能被服务器理解。
404 Not Found:被请求的文档不在服务器上。
505 HTTP Version Not Supported:服务器不支持请求报文使用的HTTP协议版本。
HTTPS
HTTPS = HTTP + SSL/TLS
在HTTPS数据传输的过程中,需要用SSL/TLS对数据进行加密和解密,需要用HTTP对加密后的数据进行传输。
SSL(安全套接字层),是为网络通信提供安全及数据完整性的一种安全协议。TLS(安全传输层协议),建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本。
密码学基础
明文:指未被加密过的原始数据。
密文:明文被某种加密算法加密之后,会变成密文。密文可以被解密得到明文。
密钥:是在明文转换为密文或将密文转换为明文的算法中输入的参数。分为对称密钥与非对称密钥,分别应用在对称加密和非对称加密上。
对称加密:对称加密又叫做私钥加密,即信息的发送方和接收方使用同一个密钥去加密和解密数据。
加密过程:明文 + 加密算法 + 私钥 => 密文
解密过程:密文 + 解密算法 + 私钥 => 明文
非对称加密:非对称加密也叫做公钥加密。非对称加密与对称加密相比,其安全性更好。非对称加密使用一对密钥,即公钥和私钥,且二者成对出现。私钥被自己保存,不能对外泄露。公钥指的是公共的密钥,任何人都可以获得该密钥。用公钥或私钥中的任何一个进行加密,用另一个进行解密。
被公钥加密过的密文只能被私钥解密,过程:
明文 + 加密算法 + 公钥 => 密文, 密文 + 解密算法 + 私钥 => 明文
被私钥加密过的密文只能被公钥解密,过程:
明文 + 加密算法 + 私钥 => 密文, 密文 + 解密算法 + 公钥 => 明文
HTTPS传输过程
HTTPS在传输过程中同时使用了对称加密和非对称加密。对数据进行对称加密,对称加密所要使用的密钥通过非对称加密传输。在传输的过程中会涉及到三个密钥:服务器端的公钥和私钥,用来进行非对称加密;客户端生成的随机密钥,用来进行对称加密。
1.客户端向服务器发起HTTPS请求,连接到服务器的443端口。
2.服务器端有一个密钥对,即公钥和私钥,是用来进行非对称加密使用的,服务器端保存着私钥,不能将其泄露,公钥可以发送给任何人。
3.服务器将自己的公钥发送给客户端。
4.客户端收到服务器端的公钥之后,会对公钥进行检查,验证其合法性,如果发现发现公钥有问题,那么HTTPS传输就无法继续。严格的说,这里应该是验证服务器发送的数字证书的合法性,关于客户端如何验证数字证书的合法性,下文会进行说明。如果公钥合格,那么客户端会生成一个随机值,这个随机值就是用于进行对称加密的密钥,我们将该密钥称之为client key,即客户端密钥,这样在概念上和服务器端的密钥容易进行区分。然后用服务器的公钥对客户端密钥进行非对称加密,这样客户端密钥就变成密文了,至此,HTTPS中的第一次HTTP请求结束。
5.客户端会发起HTTPS中的第二个HTTP请求,将加密之后的客户端密钥发送给服务器。
6.服务器接收到客户端发来的密文之后,会用自己的私钥对其进行非对称解密,解密之后的明文就是客户端密钥,然后用客户端密钥对数据进行对称加密,这样数据就变成了密文。
7.然后服务器将加密后的密文发送给客户端。
8.客户端收到服务器发送来的密文,用客户端密钥对其进行对称解密,得到服务器发送的数据。这样HTTPS中的第二个HTTP请求结束,整个HTTPS传输完成。
数字证书
在HTTPS的传输过程,当服务器接收到客户端发来的请求时,会向客户端发送服务器自己的公钥,公钥有可能中途被篡改。因此需要用数字证书来让客户端信赖这个公钥是自己想要访问的服务器的公钥。
CA(证书认证中心)专门对公钥进行认证。CA本身也有一对公钥和私钥,CA会用自己的私钥对要进行认证的公钥进行非对称加密,此处待认证的公钥就相当于是明文,加密完之后,得到的密文再加上证书的过期时间、颁发给、颁发者等信息,就组成了数字证书。
不论什么平台,设备的操作系统中都会内置100多个全球公认的CA,说具体点就是设备中存储了这些知名CA的公钥。当客户端接收到服务器的数字证书的时候,会进行如下验证:
1.首先客户端会用设备中内置的CA的公钥尝试解密数字证书,如果所有内置的CA的公钥都无法解密该数字证书,说明该数字证书不是由一个全球知名的CA签发的,就无法信任该服务器的数字证书。
2.如果有一个CA的公钥能够成功解密该数字证书,说明该数字证书就是由该CA的私钥签发的,因为被私钥加密的密文只能被与其成对的公钥解密。
3.除此之外,还需要检查客户端当前访问的服务器的域名是与数字证书中提供的“颁发给”这一项吻合,还要检查数字证书是否过期等。
Cookie与Session
Cookie
在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用cookie只能存储一些小量的数据。
Session
session和cookie的作用有点类似,都是为了存储用户相关的信息。不同的是,cookie是存储在本地浏览器,而session存储在服务器。存储在服务器的数据会更加的安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,一些session信息还是绰绰有余的。
Cookie与Session的结合使用
1.存储在服务端:通过cookie存储一个session_id,然后具体的数据则是保存在session中。如果用户已经登录,则服务器会在cookie中保存一个session_id,下次再次请求的时候,会把该session_id携带上来,服务器根据session_id在session库中获取用户的session数据。就能知道该用户到底是谁,以及之前保存的一些状态信息。这种专业术语叫做server side session。
2.将session数据加密,然后存储在cookie中。
DNS
主机的一种标识方式是用主机名,但主机名可能由不定长的字母数字组成,路由器难以处理,所以主机也可以使用IP地址进行标识。TCP/IP网络通过IP地址来确定通信对象。因此,需要一种能进行主机名到IP地址转换的目录服务,这就是DNS(域名系统)。
DNS
1.一个由分层的DNS服务器实现的分布式数据库;
2.一个使得主机能够查询分布式数据库的应用层协议。
DNS工作的简单例子
在浏览器中请求URL www.someschool.edu/index.html页面时,为了使用户的主机能够将HTTP请求报文发送到Web服务器www.someschool.edu,必须获得该服务器的IP地址,具体如下:
1.客户端主机上运行着DNS应用的客户端。
2.浏览器从URL中抽取出主机名www.someschool.edu,并将主机名传给DNS应用客户端。
3.DNS客户向DNS服务器发送一个包含主机名的请求。
4.DNS服务器返回给DNS客户请求主机名对应的IP地址。
5.客户端向位于收到IP地址80端口的HTTP服务器进程发起一个TCP连接。
DNS解析器
对于DNS服务器,我们计算机上有相应的DNS客户端,该客户端的部分称为DNS解析器。通过DNS查询IP地址的操作称为域名解析,负责执行解析操作的就叫解析器。
解析器实际是一段程序,包含在操作系统的Sokect库中。Sokect库是用于调用网络功能的程序组件集合,可以用于发送和接收数据。根据主机名查询IP地址时,浏览器会使用Socket库中的解析器。因此,在编写浏览器等应用程序时只需要调用解析器的gethostbyname()函数即可。
DNS服务器基本工作
来自客户端的查询消息包含3种信息:
(a)主机名
服务器、邮件服务器(邮件地址中@后面的部分)的名称
(b)Class
早期的DNS设计方案中,也考虑了DNS在互联网以外的其他网络的应用,用Class来识别网络信息,由于如今只有互联网,因此Class的值为IN。
(c)记录类型
表示主机名对应何种类型的记录。当类型为A时,表示对应IP地址;当类型为MX时,表示对应邮件服务器。
主机名 | Class | 记录类型 | 响应数据 |
---|---|---|---|
www.xxxx.com | IN | A | 192.0.1.x |
gler.com | IN | MX | 922mail.gler.com |
mail.gler.com | IN | A | 192.0.2.y |
… | … | … | … |
DNS服务器会从域名与IP地址的对照表中查找相应的记录,并返回IP地址。
DNS服务器层次结构与工作原理
- 根DNS服务器
有400多个根DNS服务器遍及全世界,由13个不同的组织管理。根DNS服务器提供TLD服务器的IP地址。 - 顶级域(TLD)DNS服务器
对于每个顶级域(如com、org、net、edu和gov)和所有的国家的顶级域(如uk、fr、ca和jp)都有TLD服务器。TLD服务器提供权威DNS服务器的IP地址。 - 权威DNS服务器
在因特网上具有公共可访问主机的每个组织机构必须提供可访问的DNS记录,这些记录将这些主机的名字映射为IP地址。
除去在DNS服务器层次结构中的3种,还有一种DNS服务器,本地DNS服务器。每一个ISP都有一台本地DNS服务器。
比如主机cse.nyu.edu想知道gaia.cs.umass.edu的IP地址。
1.请求主机向邻近的本地DNS服务器发送一个DNS查询报文,该报文含有被转换主机名gaia.cs.umass.edu。
2.本地DNS服务器将查询报文转发到根DNS服务器。
3.根DNS服务器注意到edu的前缀并向本地DNS服务器返回负责edu的TLD的IP地址列表。
4.本地DNS服务器再次向这些TLD服务器之一发送查询报文。
5.该TLD服务器注意到umass.edu前缀,并用权威DNS服务器的IP地址进行响应。
6.本地DNS服务器直接向dns.umass.edu重发查询报文。
7.dns.umass.edu用gaia.cs.umass.edu的IP地址进行响应。
8.本地DNS服务器将gaia.cs.umass.edu的IP地址响应给请求主机。
在这一条DNS查询链中,从请求主机到本地DNS服务器的查询是递归查询;其余查询是迭代查询。
DNS缓存
在上面的查询中共发送了8分DNS报文,4份查询报文和4份响应报文。为了改善时延性能并减少DNS的报文传输数量,采用了DNS缓存技术。
DNS请求可以不需要从根域开始查找,因为DNS服务器有一个缓存,可以记住之前查询过的主机名。如果要查询的主机名和相关信息已经在缓存中,那么就可以直接返回响应,接下来的查询可以从缓存的位置开始向下进行。相比每次都从根域找起来说,缓存可以减少查询所需的时间。并且,当要查询的域名不存在时,“不存在”这一响应结果也会被缓存。这样,当下次查询这个不存在的域名时,也可以快速响应。同时DNS服务器保存的缓存数据会有一个有效期,当数据超过有效期后,就会进行删除。
三、运输层
应用 | 应用层协议 | 下面的运输协议 |
---|---|---|
电子邮件 | SMTP | TCP |
远程终端访问 | Telnet | TCP |
Web | HTTP | TCP |
文件传输 | FTP | TCP |
远程文件服务器 | NFS | 通常UDP |
流式多媒体 | 通常专用 | UDP或TCP |
因特网电话 | 通常专用 | UDP或TCP |
网络管理 | SNMP | 通常UDP |
域名转换 | DNS | 通常UDP |
UDP
UDP报文段结构
UDP的主要特点:
1.关于发送什么数据以及何时发送的应用层控制更为精细。采用UDP时,只要应用进程将数据传递给UDP,UDP就会将数据打包进UDP报文段并立即将其传递给网络层。
2.无需建立连接。
3.无连接状态。UDP不维护连接状态,也不跟踪参数。
4.分组首部开销小。UDP仅有8字节的开销。
5.尽最大努力交付。UDP容忍一些数据丢失。
6.支持一对一、一对多、多对一和多对多的交互通信。
TCP
TCP报文段结构
标志字段:
URG:紧急指针有效
ACK:确认序号有效(用来应答的)
SYN:发起一个新连接(用来同步的)
PSH:接收方应该尽快将这个报文交给应用层
RST:重置连接
FIN:释放一个连接
TCP的主要特点:
1.面向连接的。使用TCP的两个进程在发送数据之前必须先相互“握手”。
2.提供可靠的数据传输。
3.TCP连接是点对点的。
4.TCP连接提供全双工服务。
5.面向字节流。
TCP连接管理
引用自猿人谷:面试官,不要再问我三次握手和四次挥手
三次握手
为什么需要三次握手,两次不行吗?
1 第一次握手:客户端发送网络包,服务端收到了。
这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
2 第二次握手:服务端发包,客户端收到了。
这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
3 第三次握手:客户端发包,服务端收到了。
这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
因此,需要三次握手才能确认双方的接收与发送能力是否正常。
三次握手过程中可以携带数据吗?
第三次握手的时候,可以携带数据,第一次、第二次握手不可以携带数据。第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以可以携带数据。
四次挥手
挥手为什么需要四次?
因为当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手。
四次挥手释放连接时,等待2MSL的意义?
MSL是Maximum Segment Lifetime的英文缩写,译为“最长报文段寿命”,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
为了保证客户端发送的最后一个ACK报文段能够到达服务器。因为这个ACK有可能丢失,从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK,接着客户端再重传一次确认,重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。
快速重传
TCP采用的是累计确认机制,即当接收端收到比期望序号大的报文段时,便会重复发送最近一次确认的报文段的确认信号,称之为冗余ACK。
报文段1成功接收并被确认ACK 2,接收端的期待序号为2,当报文段2丢失,报文段3失序到来,与接收端的期望不匹配,接收端重复发送冗余ACK 2。如果在超时重传定时器溢出之前,接收到连续的三个重复冗余ACK(其实是收到4个同样的ACK,第一个是正常的,后三个才是冗余的),发送端便知晓哪个报文段在传输过程中丢失了,于是重发该报文段,不需要等待超时重传定时器溢出,大大提高了效率。这便是快速重传机制。
3次冗余ACK的原因是即使发送端是按序发送,由于TCP包是封装在IP包内,IP包在传输时乱序,意味着TCP包到达接收端也是乱序的,乱序的话也会造成接收端发送冗余ACK。那发送冗余ACK是由于乱序造成的还是包丢失造成的,这里便需要好好权衡一番,因为把3次冗余ACK作为判定丢失的准则其本身就是估计值。
四、代理服务器
正向代理
反向代理
参考资料
- 《网络是怎样连接的》
- 《计算机网络自顶向下方法》
- 猿人谷:面试官,不要再问我三次握手和四次挥手
- HTTP协议详解
- TCP的快速重传机制