从零开始的计算机网络基础(图文并茂,1.8w字,面试复习必备)
Lazy.Cat 人气:2
## 前言
在互联网高速发展的今天,我们通过手机,电脑等通讯设备可以很轻松达到`未出茅庐便知天下事`的境界。每天我们都要访问数不胜数的网站,通过打开浏览器,输入网址两步搞定。当然更为常规的做法是打开浏览器,设置首页为某个搜索引擎网站(如百度,谷歌),在搜索框中输入想要访问的关键词,几秒的功夫一个个网站就呈现在客官眼前任由客观挑选。但,,,你有没有想过为什么只是输了个网址怎么页面就呈现出来了呢?
![preword.jpg](https://user-gold-cdn.xitu.io/2020/4/25/171af950ffc60bba?w=500&h=341&f=jpeg&s=133772)
## 初探计算机网络
### 网络
网络的概念是指一组具有通信功能的设备相互连接形成的。什么叫具有通信功能的设备呢?这个可以分为主机,如电脑、手机等;以及连接设备如路由器,交换机,调制解调器等。此时这些连接设备对于你来说可能只是个抽象的名词,不过没关系,之后我都会一一讲到,请耐心地看下去。
### 局域网,广域网,互联网络
局域网(LAN),通常是私有的,用于连接一个办公室,一栋教学楼,一个工作室等等。
如下图,处于同一个局域网的用户A,B。A可以联系到B,但却不能联系到处于另一个局域网的C。
![image1.jpg](https://user-gold-cdn.xitu.io/2020/4/25/171af950fdd09cea?w=1296&h=535&f=jpeg&s=37750)
广域网(WAN),广域网相比于局域网,有着更大的地理覆盖范围。可以覆盖一个城市,一个省,一个国家,甚至全世界。
如下图,广域网由一个个子网络连接而成,并且广域网中的子网络之间可以正常通信。
![image2.jpg](https://user-gold-cdn.xitu.io/2020/4/25/171af951025a88b1?w=1306&h=508&f=jpeg&s=41435)
互联网络,几乎不存在孤立的局域网或广域网,它们都相互连接在一起。当两个或多个网络连接起来,就形成了一个互联网络。
![internet.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95102a6bbee?w=899&h=142&f=png&s=58540)
### 信息交换
由图1,图2我们很容易产生网络之间和同一网络下的用户之间的通信方式是一样的错觉。所以看到图3很疑惑欸,箭头没有了,虚线来了,路由器和交换机也来了。。别忙着揍我,先听我解释。
#### 电路交换网络
两个终端之间始终保持一条专用连接,由交换机进行转发。由图可以发现连接两个子网的线路更“粗”,这是因为每个终端都需要一个专用连接,所以线路的带宽更大,也就更“粗”了。
![circuit-switched.png](https://user-gold-cdn.xitu.io/2020/4/25/171af951043c04c5?w=663&h=225&f=png&s=84109)
#### 分组交换网络
同一个子网络的终端之间依然保持一条专用连接,但子网间的通信不再为所有的终端建立专用连接,而是一个固定大小的线路,每个消息根据到达先后顺序排队,每次取不大于线路带宽的消息进行转发。细心的同学会发现上图的交换机这里变成了路由器,其实路由器也拥有交换机信息转发的功能,但除此之外还增加了一个网络层用于IP寻址。这是网络间通信的关键,之后会在网络层中详细讲解。
![router-switch.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95105cf8733?w=686&h=259&f=png&s=71892)
#### 为什么信息交换中既用交换机又用路由器
如图3,既使用了电路交换网络,又使用了分组交换网络。之前谈到过,路由器比交换机多了一个网络层,因此进行数据转发时花费的时间更多,使用交换机进行子网内部数据转发更加合适。而子网间通信之所以更多选取分组交换网络,是因为虽然分组交换需要排队会带来一些时延,但比电路交换成本更加低廉,资源利用率也更高。
### 网络分层
#### 为什么要分层??这里是一个例子
假如夏尔和慕恩是一对高三小情侣,为了防止亲密的信息被父母看到,他们决定对会话进行加密,享受美好的二人时光。
![example1.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95186a7698a?w=963&h=702&f=png&s=56086)
从以上可以看出,夏尔和慕恩之间的通信从上到下分为三层,第一层负责读/写消息,第二层负责加密/解密消息,第三次层责发送/接收。每一层相互对应,层与层之间互不干扰,每层都做自己分内的事。
#### TCP/IP协议簇
![tcp_cen.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95187214cf2?w=998&h=425&f=png&s=145498)
网络传输也采用这个思想,将复杂的传输过程,分为一个个层次模块。模块内部接收上一层传递的信息然后进行处理,处理结束后呈递到下一层。
这里说一下为什么路由器接收和发送不使用同一个链路。因为虽然路由器有同一个网络层,但它涉及到n个链路和物理层协议的任意组合,路由器接收基于一对协议的链路1再把它投递到基于另一对协议的链路2。而交换机虽然含两层,但两层在同一个协议集中。
关于各层次的功能特点会在之后的内容中详细介绍。
## 应用层
### 从一个例子说起
眼看情人节到了,夏尔少爷成功熬过12点,准点发送了情人节快乐的消息。消息经应用处理为报文通过下面几层网络成功传递到慕恩那里。慕恩开心地看着手机发呆。。。
![image2.png](https://user-gold-cdn.xitu.io/2020/4/25/171af951a67c6d56?w=814&h=549&f=png&s=40665)
### 你说的太简单了,我需要更多的力量(知识)
#### 进程通信
两个终端间的通信本质上是终端操作系统中进程之间的通信。
两个不同系统中的进程,通过计算机网络交换报文而相互通信。
操作系统中的进程是CPU资源分配的最小单位,一个进程可以被认为是运行终端系统中的一个程序。
![image.png](https://user-gold-cdn.xitu.io/2020/4/25/171af951c55f9d07?w=693&h=532&f=png&s=12735)
上图是一个终端间进程通信的简单示意图。我们可以把进程比作一个房子,socket就像房子的大门,报文通过大门经传输层-网络层-数据链路层-物理层传输到目的地。再自下而上地去掉各层首部。
#### 报文
在图8所示的流程中,应用层所关心的只有一个,那就是报文。应用层协议定义了运行在不同端系统上的应用进程如何相互传递报文。应用层协议定义了:
1. 报文的类型(响应报文/请求报文)。
2. 报文类型的语法(如HTTP协议中请求报文首行是请求方法,请求地址,协议;而响应报文首行是协议,状态码,描述)。
3. 字段的语义(字段对应的信息含义)。
4. 一个进程何时以及如何发送报文,对报文进行响应的规则。
### 你所应当了解的应用层协议
#### 如何让报文携带协议信息呢
很容易想到可以让报文携带协议的标记字段,然后到达目的地后再检查该字段。那么具体如何实现呢?其实只需要将协议标识的首部字段加在报文的首部,然后随报文发送而发送。检测的话,取下首部字段,按协议要求将数据报文发送给首部字段对应的socket即可。
#### http协议
![http.png](https://user-gold-cdn.xitu.io/2020/4/25/171af951b6218fe2?w=548&h=328&f=png&s=60859)
##### 定义:
超文本传输协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。简单来说http协议起到了一个让你点击网站后能得到页面反馈的作用。
##### http1.0
在http早期,每个http请求都要求打开一个tcp socket连接,并且使用一次之后就断开这个tcp连接。
##### http1.1
http1.1可以使用keep-alive可以改善这种状态,即在一次TCP连接中可以持续发送多份数据而不会断开连接。通过使用keep-alive机制,可以减少tcp连接建立次数,也意味着可以减少TIME_WAIT状态连接,以此提高性能和提高httpd服务器的吞吐率。但是keep-alive timeout时间也不是越长越好,长时间的tcp连接容易导致系统资源无效占用,因此设置合理的keep-alive timeout时间很重要
##### http2.0
1. 多路复用。建立一个tcp连接,一个连接上有任意多个流,报文消息分割为一个帧或多个帧在字节流里面并发传输,值得注意的是同一报文的若干帧必须在同一字节流上进行传播。等待报文帧传输完成后再进行消息重组。
2. 二进制分帧。将传输的报文划分为首部和消息负载两个帧,并采用二进制编码。
3. 首部压缩:客户端与服务端维护一份相同的静态字典,里面保存了常用请求头的名称和值,对于字典中只有名称没有值的首部,在传输时需要先索引其值在用哈夫曼编码减少体积,客户端和服务端还会维护一个动态字典用于存放请求用到的头部,后续传播就可以只传索引,
4. 服务器推送:服务端可以主动向客户端推送资源。
##### http和https的区别
1. http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
2. http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
3. https协议需要ca证书,费用较高。
4. 使用不同的链接方式,端口也不同,一般而言,http协议的端口为80,https的端口为443
##### 证书验证
浏览器使用内置的根证书中的公钥来对收到的证书进行认证,如果一致,就表示该安全证书是由可信任的颁证机构签发的,这个网站就是安全可靠的;如果该SSL证书不是根服务器签发的,浏览器就会自动检查上一级的发证机构,直到找到相应的根证书颁发机构,如果该根证书颁发机构是可信的,这个网站的SSL证 书也是可信的。
##### ssl握手过程
1. 客户端向服务端发出加密通信的请求。这被叫做clientHello请求,
- 包括支持的协议版本,一个随机数用于等会生成会话密钥,支持的加密方法,支持的压缩方法
2. 回应,serverhello,
- 确认加密通信协议的版本,一个随机数用于稍后生成会话密钥,确定加密方法,服务器的证书
3. 客户端验证服务端证书是否为可信机构颁步,如果不可信会给访问者一个警告有起决定是否继续通信,
- 返回一个随机数用于公钥加密,编码改变通知(之后的信息都用双方商定的加密方法和密钥发生),客户端握手结束的通知
4. 服务端收到客户端的第三个随机数后,计算生成本次会话用的“会话密钥”,然后向客户端发送下面信息:
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。
http协议实在太重要,涉及到的知识点比较多,这里只是浅尝辄止。之后会单开一篇文章专门讲http协议,当然这里推荐三元大佬写的文章[HTTP灵魂之问,巩固你的 HTTP 知识体系](https://juejin.im/post/5e76bd516fb9a07cce750746).
##### 为什么ssl证书有过期时间
最重要的原因在于吊销。当网站丢失了私钥后,应该向证书颁发机构(ca)申请将其证书放入吊销列表。如果证书永久有效,吊销列表越来越大,会给浏览器和ca机构增加很大的流量压力。而如果有过期时间,那么ca可以剔除过期的网站,浏览器也不信任过期的证书。
#### ftp
![ftp.png](https://user-gold-cdn.xitu.io/2020/4/25/171af951c61cc131?w=734&h=382&f=png&s=65593)
如上图,ftp协议作为一个文件传输协议,它的基本流程如下:
1. 用户提供远程服务器上注册的uid和password进行用户认证,认证成功后建立TCP连接。
2. 用户通过ftp用户接口从本地的文件系统中上传文件经TCP连接到达远TCP端服务器。
3. 远端服务器将文件写入远程文件系统,至此一个文件上传到远端服务器的工作完成。
##### 与http协议的异同
ftp和http都是文件传输协议,并且传输层都基于TCP协议。
而他们最显著的区别在于ftp协议使用了两个并行的TCP连接(控制连接和数据连接)来保证数据的传输。控制连接主要用于上述提到的用户认证以及文件存取标识(也就是标识当前是读取文件还是存放文件)等;数据连接用于传输文件数据。
http默认端口是80;ftp默认端口是20和21
![ftp2.png](https://user-gold-cdn.xitu.io/2020/4/25/171af9520a571ee1?w=628&h=158&f=png&s=37866)
#### dns
dns是一个域名解析协议,通常会配合其他应用层协议完成相应的需求。在谈dns之间需要先明确几个概念,分别是域名,ip地址,用户主机地址(mac地址)。
##### 域名
域名可以被近似地看作ip地址的别名,简单来说就是你每天看到的各种网站。有一个形象的比喻是:ip地址就像你的SFZ号,而域名就像你的名字一样,名字比SFZ号更容易记忆。但有所不同的是域名不会发生重名的情况(想想为什么不能)。
##### ip地址
主机的主板上有一块名为网卡的硬件,它内部考录了mac地址,用于标识一台主机的物理地址。但由于不同厂商指定的标准不同,mac地址的编址方式也是千奇百怪。这是有人提出:创建一个逻辑层,用虚拟的ip地址映射真实的mac地址,再将ip地址的编址方式制定为一个全球通用的标准就行了。因此ip地址实际上是一个逻辑上的地址,但我们暂时不用关注ip地址和mac地址如何映射的,将ip地址视为电脑主机的网络地址标识即可。
##### mac地址
主机的物理地址,用于唯一标识一台主机的。当然一台主机不一定只有一个网卡,比如笔记本电脑通常含一个有线网卡和一个无线网卡。
##### dns解析流程
其实最早的域名解析是采用本地文件hosts文件进行解析的,但随着互联网网站越来越多,显然用文件解析的方式不符合这样的需求。steam玩家对此应该不陌生:
![hosts.png](https://user-gold-cdn.xitu.io/2020/4/25/171af9520d4a1585?w=507&h=268&f=png&s=18350)
一个域名的解析顺序如下:
![dns1.png](https://user-gold-cdn.xitu.io/2020/4/25/171af952216448a8?w=553&h=406&f=png&s=15688)
如果夏尔的域名是 **ciel.jialidun.edu**,慕恩的域名是**moon.nannvnan.edu**,那么夏尔的主机是怎么获取慕恩的ip呢?
![dns2.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95237d2af0e?w=528&h=599&f=png&s=89246)
emmm,是不是跟想象中的有点不一样呢,接下来听我一一道来。首先弄清楚上图中各个dns服务器到底有怎样的职责。
##### dns分布式结构
dns服务器大体上可分为根服务器,顶级域服务器,权威服务器。
1. 根服务器类似于树的根部,属于dns服务器的顶层,多数部署在北美洲。
2. 顶级域服务器,常见的 `com cn edu org ` ,比如代表国家的`cn uk ca` 等。
3. 权威服务器,在因特网上具有公共可访问的主机。如学校,大型公司等机构。
![dns3.png](https://user-gold-cdn.xitu.io/2020/4/25/171af952441eb7a3?w=956&h=369&f=png&s=188018)
那么之前的流程就很好解释了,夏尔发送了域名解析请求,其中包括源域名和目标域名。
1. 本地权威服务器会接收到该请求并查看目标域名是否是自己的管辖区域,如果不是它将把该请求转发给根服务器。
2. 根服务器会查询目标域名的顶级域(如这里的`edu`),然后将分管该顶级域的顶级域服务器ip发给本地服务器,本地服务器再向顶级域服务器转发请求。
3. 顶级域服务器收到请求后会查询该域名属于哪个权威服务器管辖,然后将查询结果返回给本地服务器。
4. 本地服务器将请求转发给目标服务器,目标服务器再根据域名查询相应的ip地址再将结果返回给本地服务器。
5. 本地服务器将目标域名的ip返回给夏尔的主机。
但是实际上dns查询可能并不会完全遵守上述流程,试想每天有上亿人访问谷歌百度等,如果每个人的访问都要经历这样冗长的流程,对于用户体验和服务器性能来说是灾难性的。而解决方案则是使用一个缓存的机制,将用户访问过的网站ip地址进行缓存,查询时直接从缓存中取。这里只是简单谈谈,更多的细节会在http协议中详细讲解。
##### 应用层协议对应传输层协议
| 应用层协议 | 传输层协议 | 应用 |
| :--------: | :--------: | :----------: |
| HTTP | TCP | Web |
| FTP | TCP | 文件传输 |
| DNS | TCP/UDP | 域名解析 |
| SMTP | TCP | 电子邮件 |
| Telnet | TCP | 远程终端访问 |
| RIP | UDP | 路由选择协议 |
##### DNS何时用TCP协议,何时用UDP协议
1. DNS在进行区域传输的时候使用TCP协议,其它时候则使用UDP协议;
DNS的规范规定了2种类型的DNS服务器,一个叫主DNS服务器,一个叫辅助DNS服务器。在一个区中主DNS服务器从自己本机的数据文件中读取该区的DNS数据信息,而辅助DNS服务器则从区的主DNS服务器中读取该区的DNS数据信息。当一个辅助DNS服务器启动时,它需要与主DNS服务器通信,并加载数据信息,这就叫做区传送(zone transfer)。
2. UDP报文的最大长度为512字节,而TCP则允许报文长度超过512字节。**当DNS查询超过512字节时,协议的TC标志出现删除标志**,这时则使用TCP发送。通常传统的UDP报文一般不会大于512字节。 因此在区传送中使用TCP协议。
## 传输层
### 从另一个例子讲起
一天,夏尔学习到很晚肚子饿了,于是他熟练地打开美团,点了一份炸鸡套餐。不一会儿外卖小哥就将一份香喷喷的炸鸡送到夏尔的快乐椅前了。。。
![kfc.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95263ecef21?w=675&h=562&f=png&s=54611)
从之前的知识我们可以猜想到`我想吃脆皮炸鸡`这段报文是由应用层协议负责的。那么报文信息的传递是怎么实现的呢?从上图可以看出夏尔与肯德基之间仿佛通过美团外卖在逻辑上建立了连接,但将炸鸡送到夏尔家确实由外卖员在物理层面建立的连接。说到这里是不是有点感觉了呢,传输层的作用就是在两个终端之间建立逻辑连接,而网络层的作用则是实打实地建立了两个终端地址的连接。(之前有提到网络层其实也是抽象的逻辑连接,这个问题先按下不表,之后网络层会有所解答)
#### 为什么需要逻辑连接(传输层)呢
根据之前的知识我们知道路由器中最顶层的是网络层,也就是说分组交换中根本用不到传输层,那么费尽周折地弄一个传输层有什么意义呢?我们知道微信可以视频聊天,可以语音聊天,可以文字聊天。那么假如夏尔和慕恩有特殊癖好(视频聊天的同时打字聊天),夏尔和慕恩的ip地址都是暂时固定的,那么文字流和视频流都会在这两个ip地址间进行传递。那么问题来了,我们知道视频聊天服务和文字聊天服务肯定是两个会话服务,那么怎么将文字流交给文字会话,视频流交给视频会话呢?本着遇事不决量子力学的态度,我们大胆猜想可以在报文上加标记,这就是传输层所着手解决的一个问题,当然传输层的作用还不止这些。
#### 传输层怎么实现端到端会话传输的呢
##### 多路分解和多路复用
![image.png](https://user-gold-cdn.xitu.io/2020/4/25/171af951c55f9d07?w=693&h=532&f=png&s=12735)
不知道大家对这张图还没有印象,之前提到过报文由应用程序进程通过socket呈递给传输层到站后再通过传输层分发到相应socket由另一个终端的应用程序接收。我们可以近似地把进程理解为会话,而socket是进程与传输层之间的桥梁。
多路分解:将运输层报文段中的数据交付到正确的套接字(socket)。
多路复用:在源主机从不同套接字中收集数据块,并未每个数据块装上首部信息(标记)从而生成报文段,然后将报文段传递到网络层。
值得一提的是多路分解和多路复用并不是传输层所特有的,它们是所有计算机网络都需要的。
##### 端口
了解了多路分解和多路复用后,我们知道套接字应该是具有唯一标识的桥梁,同时它还要告知行人这座桥通向何处。这就引申出了端口这个概念,端口分为源端口号(从哪来)和目的端口号(到哪里去)。报文分别用了16个比特位标识源端口和目的端口,也就是说端口的范围在0-65535之间。同时0-1023端口是受限制的(被一些很重要的诸如http协议等使用了)。之前提到过http协议默认占用80端口,你可以试试下面链接跟你平时看到的度娘相比有什么不同。[http://www.baidu.com:80](http://www.baidu.com:80)
### 传输层双雄
#### UDP和TCP的区别
1. tcp是面向连接的,udp是无连接的
2. tcp提供可靠交互,报文传输无差错,不丢失,不重复地按序到达,而udp是尽可能地实现交互,即提供不可靠交互
3. tcp是面向字节流,udp面向报文。应用层一次发送给tcp一个数据块,tcp将其视为无结构字节流,tcp中有一个缓存,当应用程序数据块太长tcp会将其划分为更小的块传输。而udp则无论应用层发送多大的报文都会照样直接发送,因此应用层必须选择合适的报文大小,太长ip层需要分片,降低效率;太短,ip太小。
4. tcp支持1对1的交互,udp支持1对1,1对多,多对多的交互
5. tcp首部为20个字节,udp首部只占8字节
6. 文件,邮件用tcp,视频用udp
因为双雄各有千秋,所以有各自适应的场景。总的来说udp无论是首部开销还是无连接的特点都使得其速度比tcp快,但在可靠交互,流量控制和拥塞处理这方面tcp显然是更好的一方。
### UDP
#### 报文结构
![udp.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95267c8f852?w=339&h=309&f=png&s=90351)
##### 源端口号,目的端口号
目的端口号是为了报文到站后寻找合适的socket,那么为什么要把源端口号也带上呢?因为连接是全双工模式,也就是说接收方既是发送方也是接收方,当接收方想反馈信息给发送方时只需要从报文中获取源端口号作为反馈报文的目的端口号即可。
##### 长度
一组报文的长度,用于分割报文组同时检测是否出现丢包现象。
##### 校验和
16比特位,用于检验报文是否在发送过程中受外界干扰出现了比特改变的情况。(我们知道数据最终是由电缆或光缆或电磁波传递的,物理学上外界环境可能会影响这些信号,比如使得高电平变为低电平对应到比特位就是将1变为了0)
校验原理:
1. 将udp报文中的所有16位比特字进行相加
2. 将比特字相加的结果转换为其反码(如果有溢出,它要被回卷),作为其检验和
3. 接收方将所有16位比特字相加(包括检验和),查看结果是否为1111111111111111
```
//假定,udp首部有这三个16位比特 0110011001100000 0101010101010101 1000111100001100
0110011001100000
+ 0101010101010101
= 1000111100001100
+ 1000111100001100
= 0100101011000010 (这里产生了溢出将进行回卷,所谓回卷是指舍弃高位进位而在最低位+1)
反码运算是将0 => 1; 1 => 0。 0100101011000010 => 1011010100111101
//接收方
之前三个16比特 + 检验和
原码 + 补码 = 1111(源码位数个1)
所以如果不为1111111111111111,那么数据在传输过程中一定发送了比特变化。
```
#### udp的特性
1. udp是无连接的。也就是说使用udp协议传输报文,不需要事先建立一条信息通道,而是添加首部后直接交给网络层
2. udp提供不可靠交互。之前讲解udp报文字段时我们看到了虽然udp提供了差错检测的功能,但它却对差错回复无能为力。也就是说当udp接收到受损的报文时,只能将其丢弃。(也就是视频中存在的丢帧现象)
3. 面向报文。为报文添加首部后,直接交给网络层进行传递。
4. 1对1,1对多。因为不需要建立信道,所以可以实现类似网络层广播的一个效果。
### TCP
#### 报文结构
![tcp.png](https://user-gold-cdn.xitu.io/2020/4/25/171af952c092d75a?w=543&h=514&f=png&s=201648)
##### 序号和确认号
用于建立连接(创建传输信道),断开连接。同时也是实现可靠数据传输的关键,之后会更多地讨论。
##### 首部长度和保留未用
TCP首部的长度是可变的,首部长度字段用于将首部与数据字段区分开。保留未用如其名,为保留字段。
##### URG,ACK,PSH,RST,SYN,FIN
各占一个比特位。ACK比特用于指示字段中的值是有效的,RST,SYN和FIN用于建立和断开连接,URG用于标记报文段是否为“紧急”的数据,PSH被置1时,接收方应该立即将数据交给上传。(实践中,PSH,URG并没有使用)
##### 紧急数据指针
指向紧急数据尾部的指针,与URG配合使用。(实践中并没有用到)
##### 接收窗口
用于流量控制,之后会详细地讲解。
##### 选项
通常为空,该字段用于发送方与接收方协商最大报文字段长度时,或在告诉网络环境下用作窗口调节因子时使用。
#### 建立连接
##### 三次握手
![3](https://user-gold-cdn.xitu.io/2020/4/25/171af952cdcad130?w=1364&h=768&f=gif&s=111217)
1. 客户端发送一个syn=1连接请求和一个序列号seq=x,然后客户端进入syn_send状态,等待服务器的确认
2. 服务器收到客户端的syn请求,需要对syn进行确认于是将ack=x+1,然后将序列号seq=y;最后将上述信息放到一个报文段中发送给客户端,服务器进入syn_receive状态
3. 客户端收到服务端的确认信息,ack=y+1,seq=x+1,向服务端发送ack确认报文。该报文发送完毕后连接建立完成。
##### 为什么要三次握手
主要是为了防止已经失效的请求报文段突然又传送到了服务端造成错误。举个例子,客户端向服务端发送的连接请求报文因网络原因超时,延期很久后到达服务端。服务端收到该连接请求认为是一次新的连接就像客户端发送连接确认请求,但因为该连接报文早已失效,客户端并不会响应服务端的确认信息。不过没有三次握手,服务端会认为连接已经完成,一直等待客户端发送数据,这样服务端的很多资源就浪费了。
##### SYN洪泛攻击:
- SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。
- 防范SYN攻击措施:降低主机的等待时间使主机尽快的释放半连接的占用,短时间受到某IP的重复SYN则丢弃后续请求。
##### 四次挥手
![4.png](https://user-gold-cdn.xitu.io/2020/4/25/171af952d4dc1a00?w=682&h=384&f=gif&s=107271)
1. 客户端发送一个fin=1连接关闭的请求,序号seq=u,客户端的进入fin_wait_1状态
2. 服务端收到连接释放报文段后即发出确认报文段,(ACK=1,确认号ack=u+1,序号seq=v),客户端进入fin_wait_2状态
3. 服务端向客户端发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态(FIN=1,ACK=1,序号seq=w,确认号ack=u+1)
4. 客户端收到服务端的fin报文,向客户端发送ack报文然后进入time_wait状态。服务端收到报文后关闭连接。客户端等待两个msl时间后关闭连接(ACK=1,seq=u+1,ack=w+1)
##### 为什么四次挥手
因为tcp是全双工模式,当主机1发送fin报文表示主机1没有数据要发送了,主机2收到该报文发送一个ack确认报文表示我知道主机没有要发送的数据了,但主机1还可以接收报文,主机2发送一个fin到主机1,主机1收到后表示我知道主机2也没有数据要发送了。然后双方再愉快的分手
##### 为什么等待2msl
1. 保证tcp的全双工连接能正常关闭。如果客户端直接关闭,那么ack报文可能因为网络问题导致服务端没有收到客户端的ack确认请求。那么服务端会重新发送fin报文但此时客户端已经关闭该连接因此找不到与服务端对应的连接。
2. 保证此次连接的数据段从网络中消失。如果客户端直接关闭连接,然后马上建立下一次连接,那么有可能新老连接使用的是同一个端口,旧连接因网络原因滞留在网络中的某些数据就会在新连接建立后到达服务端,这样新老连接的数据教会发生混淆
3. msl表示报文最大生存时间,2msl表示发送接收一个来回报文的最大生存时间
#### TCP协议如何来保证数据的顺序性
##### 流量控制
- 控制发送方的发送速度,让接收方来得及接收而不至于数据丢失。
- 使用滑动窗口机制,a向b发数据,建立连接时b告诉a我的接收窗口rwnd=n,因此发送窗口的字节量不能大于该窗口。当报文某一字段丢失b会向a发送一个ack报文,Ack=1,ack=上次接收到的序列号队尾+1,新的rwnd;当接收窗口满了也会发送ack报文,当数据全部接受会发送一个ack,rwnd=0
##### 拥塞控制
发送方维持一个拥塞窗口cwnd,该窗口的大小随网络拥塞程度动态变化
1. 慢开始算法:建立连接时将cwnd设置为最大报文段mss的数值,试探性发送,收到确认信息后逐倍加大cwnd的大小。cwnd有一个门限值,当cwnd < 门限则使用慢开始算法,大于使用拥塞避免,等于则两者即可。
2. 拥塞避免:与慢开算法相比,cwnd不再是逐倍数放大,而是每次加1,让其线性缓慢增长
3. 快重传:要求接收方收到一个失序报文后立即发出确认报文而不是等到需要自己发送数据时在携带该信息。当收到连续3个重复的确认信息时发送方立即重传该缺失报文
4. 快恢复:当发送方连续收到三个重复确认信息后,将慢开始门限减半,然后不执行慢开始而是使用拥塞避免算法使cwnd窗口线性增大
#### TCP协议怎么保证数据的可靠传输
##### 校验与重传策略
- 校验策略是说每一个tcp数据都会带着数据的校验和,服务端接收到tcp数据首先会验证校验和,如果验证不对,服务端将丢弃这个tcp数据和不确认收到此报文段(希望发送方重发该数据)。
- 重传策略是说,每一次数据发送是客户端都会同时起一个定时器,如果在指定时间内没有接收到服务端的确认,就把数据再发一次。定时器时长是一个动态变化的过程,简单来说是由当前网络的拥塞程度和之前定时器时长的加权平均值确立的,但对于使用快恢复算法之后的定时器则只跟当前网络拥塞程度有关。
#### TCP粘包,TCP拆包
##### TCP粘包和TCP拆包是什么
通过前面的学习我们知道,TCP协议是面向字节流需要通过Socket获取(/上传)数据。Socket大门不可能是无限大的,它存在一个最大长度。报文大小与Socket大小有下面情况
![tcp粘包](https://user-gold-cdn.xitu.io/2020/4/25/171af95316ef23a6?w=550&h=476&f=png&s=7395)
1. 如上图中的第一根**bar**所示,服务端一共读到两个数据包,每个数据包都是完成的,并没有发生粘包的问题,
2.
服务端仅收到一个数据包,这个数据包包含客户端发出的两条消息的完整信息,这个时候基于第一种情况的逻辑实现的服务端就蒙了,因为服务端并不能很好的处理这个数据包,甚至不能处理,这种情况其实就是TCP的粘包问题。
3.
服务端收到了两个数据包,第一个数据包只包含了第一条消息的一部分,第一条消息的后半部分和第二条消息都在第二个数据包中,或者是第一个数据包包含了第一条消息的完整信息和第二条消息的一部分信息,第二个数据包包含了第二条消息的剩下部分,这种情况其实是发送了TCP拆包问题,因为发生了一条消息被拆分在两个包里面发送了,同样上面的服务器逻辑对于这种情况是不好处理的。
##### 什么情况下会发生TCP粘包
1. TCP连接复用造成的粘包问题
2. TCP默认使用Nagle算法,该算法会导致TCP粘包
3. 数据包过大造成的粘包问题
4. 网络拥塞造成的TCP粘包
5. 接收方不及时接受缓存区的包,造成一次接受多个包
**如何处理粘包、拆包**
通常会有以下一些常用的方法:
1. 使用带消息头的协议、消息头存储消息开始标识及消息长度信息,服务端获取消息头的时候解析出消息长度,然后向后读取该长度的内容。
2. 设置定长消息,服务端每次读取既定长度的内容作为一条完整消息,当消息不够长时,空位补上固定字符。
3. 设置消息边界,服务端从网络流中按消息编辑分离出消息内容,一般使用‘\n’。
4. 更为复杂的协议,例如楼主最近接触比较多的车联网协议808,809协议。
## 网络层
### 没错,又是一个例子
某天,慕恩心血来潮准备给夏尔来个“飞鸽传书”,于是她情意满满地写了封信愉快的投递到邮筒A(女孩子应该挺喜欢弄点小浪漫的吧)。然后负责A-B区域的邮递员叔叔将邮件从A运输到B,然后再经过一些传递最终到达夏尔手中。
![网络层.png](https://user-gold-cdn.xitu.io/2020/4/25/171af952ef81c78d?w=1147&h=689&f=png&s=54999)
上述例子中我们着重关心一下邮筒,分解一下它的工作步骤。
1. 接收邮件(源地址)
2. 查询最近邮筒地址(因为如果超远距离传输,不可能让一个邮递员叔叔横跨几千里就为了给你俩飞鸽传书吧)
3. 转发邮件到最近的邮筒(或目标地址)。
聪明的你也想到了,这就是网络层所起到的作用。不过路由器替代了上述邮筒的功能,而路由器是怎么分组转发数据,以及路由器是怎么寻找下一个路由器的呢?请听我一一道来。
### 虚电路和分组交换
首先需要明确的是,网络层其实也分为面向连接和无连接的,被称为虚电路网络和数据报网络。与你想的一样面向连接那么需要事先建立连接管道,更多信息可以查看《计算机网络 自顶向下》。其适用于ATM机等,而因特网使用的是数据报网络,这也是我们学习的重点,所以之后主要谈的是该网络。
### 路由器工作原理
![router.png](https://user-gold-cdn.xitu.io/2020/4/25/171af952effb7e6f?w=832&h=401&f=png&s=171867)
路由器由输入端口,交换结构,输出端口,和路由选择处理器四个部分组成(注意这里的端口不同于传输层的端口,类似于物理上的接口)。
1. 输入端口: 它将一条输入的物理链路与路由器的物理层相连接,同时它能实现入链路远端的数据链路层和路由器数据链路层的交互,更为重要的是它会根据最长公共前缀匹配原则查找输出端口。
2. 交换结构:将输入端口和输出端口相连接。
3. 输出端口:输出端口从交换结构中接收分组,并将通过数据链路层和物理层传输这些分组。
4. 路由选择处理器:执行路由选择协议,维护路由选择表和连接的链路状态信息并为路由器计算转发表。
### IPv4
![ipv4.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95306cd9512?w=565&h=408&f=png&s=230635)
之前提到了很多关于ip地址,ip协议的点,但提到路由器原理时貌似没有跟ip没什么关系,是这样的吗?其实从上图数据报不难看出源地址和目的地址跟路由器的输入端口,输出端口有着千丝万缕的关系。那么首先我们还是来看看报文各字段的含义吧。
1. 版本: 规定了数据包的IP协议版本,现在使用的有ipv4和ipv6两种协议。
2. 首部长度: 分隔首部和数据字段,但大多数IP数据报具有20字节首部通常不包含该字段
3. 服务类型: 这是一个高级选项,由路由器管理员控制,可以为特定用户(VIP)提供特定等级的服务。
4. 数据报长度: IP数据报的总长度
5. 标识、标值、片偏移: 这三个字段与IP分片有关,用于保证IP分片后组装的顺序性和丢包等差错检测。
6. 寿命(TTL,相信Ping过ip地址的同学都对这个字段有所了解): 用于确保数据报不会永远在网络中循环(为什么数据报会在网络中循环呢?)。每当数据报由一台路由器处理时,该字段减1,若TTL字段减为0,则该数据报必须丢弃。
7. 首部校验和: 与之间类似,用于检测比特错误
8. 源和目的IP地址: 每台主机和路由器都有一个IP地址(不一定时公网IP),当某源生成一个数据报时,它在源IP字段中插入它的IP地址,在目的IP地址字段中插入其最终目的地的地址。
9. 选项: 选项字段允许IP首部被扩展。
10. 数据: payload,需要传输的数据
#### 点分十进制
从IPv4的数据报文中,我们得知ip地址是由32为比特标识,理论上可以由40亿公网ip地址(去年已全部分配完毕)。但32比特位表示特别不方便,于是通常我们都是用`十进制 . 十进制`进行标识,称为点分十进制。如223.0.0.1(每8个比特位用十进制标识,然后用`.`分隔)。
#### 子网掩码
ip地址是由权威机构分发的,但是不可能让一个结构给全世界每个人发一个ip地址。更合理的做法是采用之前应用过的分布式的思想,某机构向权威机构申请一部分ip地址 => 该机构向其内部人员发放ip地址。这样怎么进行划分就成了一个问题,你总不可能随机分配吧(不利于管理),所以这里就有了子网掩码的概念。`223.0.0.0/24` 中`/24`就是子网掩码,它表示该子网前24个比特位不变,后8位可以由该子网自由分配。也就是说该机构拿到了这块地址后,就可以向内部人员分配`223.0.0.1`,`223.0.0.2`,`223.0.0.99`...这样互联网就被划分为了许许多多的子网络,值得注意的时子网掩码最多30位(规定子网最少容纳两台主机)。
#### ip地址不够用咋办
但划分子网始终需要是2的倍数同时总共也就40亿个,对于信息大爆炸的今天完全不够用,那么怎么解决呢?这个问题专家们早就想到了,所以很早开始了ipv6的协议制定,当然替换一个协议相当于动摇了一个摩天大厦的根基,这务必是一个缓慢的过程。所以聪明的开发人员采用了**网络地址转换**(NAT)的方法扩充了ip地址
#### NAT
提到这个词大家估计还有点疑惑这是个啥,不过提到内网穿透,大家估计就来劲了。还是用图说一下原理吧。
![NAT.png](https://user-gold-cdn.xitu.io/2020/4/25/171af9533f181291?w=1147&h=624&f=png&s=60277)
上图简单地反映了内网穿透的原理(其实就是利用了传输层端口的多路复用)。我们知道HTTP协议的默认端口是80端口,同时用户只能访问公网ip上的信息。所以当右边的用户想要访问左边用户上的服务时,会在公网服务器上开放一个端口然后与局域网的端口连接(实际上是80端口监听时,将该请求转发到某端口),之后建立了一条通信隧道,与之类似,左边用户也与公网服务器建立一条隧道。这样看起来两个用户通过公网服务器(中介)进行相互访问一样。举个生活中的例子就是,在同一个家庭组(WIFI网络下),三大运营商只会随机分配给你一个ip,但连接该WIFI的通常不少于一人,那么虚拟子网络中的用户使用虚拟ip与其他家庭组用户之间进行通信时所用到的技术就涵盖了内网穿透。
#### ICMP
ICMP协议是一个用于差错报告的协议,它的报文类型如下
![icmp.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95355c86a63?w=604&h=463&f=png&s=175627)
### ipv6
![ipv6.png](https://user-gold-cdn.xitu.io/2020/4/25/171af953629b5571?w=483&h=265&f=png&s=95603)
从数据报就可以看出ipv6相比ipv4更加简洁清晰,删去了很多不必要的字段。然后将ip地址的比特位数从32位增加到128位,据说地球上的每一粒沙都可以分配一个ip地址。以下为字段说明:
1. 版本: 与ipv4起到的作用一样。
2. 流量类型: 标识流量的优先级。
3. 流标签: 用于标识一条数据报的流,可以按发送方的要求进行特殊处理的流,可以设置优先级(会员机制)。更多内容请参考《计算机网络 自顶向下方法》
4. 有效载荷长度: Content数据的长度
5. 下一个首部: 该字段标识数据报中内容需要交给哪一个协议(如TCP或UDP)
6. 跳限制: 数据报每经过路由转发其值-1,当其值为0时,该数据报被丢弃。与ipv4中TTL类似
#### IPv4如何向IPv6迁移
我们注意到两个协议上都有版本字段,那么是否可以通过修改该字段进行迁移呢?当然是不行的,ipv4和ipv6数据报首部完全不一样,没办法采用与原协议方法进行传输。
所以比较直接的方法是采用双栈的方法,假定两个IPv6节点要是有IPv6数据报进行交互,但他们是由中间IPv4路由器互联的。我们将两台IPv6路由器之间的中间IPv4路由器的集合称为一个隧道。隧道中,IPv6将其所有字段放到IPv4的数据报字段中,再由IPv4传输给另一个IPv6,详情参考《计算机网络 自顶向下方法》
### RIP,OSRF
之前有提到过路由选择算法,而实现路由选择有两个比较有名的协议分别是RIP和OSPF。
#### RIP
RIP是一种距离向量协议,每个路由器内部维护了一个路由选择表的RIP表,它包含了当前路由到达目标地所经历的跳数。
![rip1.png](https://user-gold-cdn.xitu.io/2020/4/25/171af953848aadbb?w=743&h=230&f=png&s=108755)
![rip2.png](https://user-gold-cdn.xitu.io/2020/4/25/171af9538c6a001f?w=463&h=217&f=png&s=45363)
#### OSPF
OSPF是基于链路状态的协议,路由器在本地运行迪杰斯特拉算法(最短路径算法),求出当前路由器据个节点的权重,然后将所有链路费用设置为1,然后如何根据权重选择链路由管理员自己决定。
#### RIP和OSPF的区别
##### 1、路由算法:
RIP协议是一种典型的距离矢量协议,它使用的也是距离矢量算法,该算法可以用一句话来概括:**进行路由更新时传递路由表。**
OSPF协议则是一种典型的链路状态协议,它使用的是Dijkstra算法,该算法是**通过OSPF邻居之间泛洪发送LSA(链路状态通告)来进行路由更新**,并且它会计算出去往所有已知目的地址的所有无环路径,以不同种类的LSA类型将其保存到LSDB(链路状态数据库)中,所有运行OSPF的设备都会有自己的LSDB,然后将LSDB中最优的LSA更新到路由表中。
##### 2、度量值:
RIP协议的度量值是以**跳数**来计算的,即每经过一跳,度量值就会加一,这样的度量值计算并不符合当前的网络环境,因为当前带宽爆炸性的增长,可能会导致RIP选择了次优路径。
OSPF协议的度量值计算则是以**带宽**为基准来计算的,其公式为10的8次方/带宽,所以从度量值的计算方式来看,OSPF要更加合理。
##### 3、最大网络直径:
RIP的最大网络直径为**15**,也就是说RIP协议所能传递路由信息的最大跳数就是15跳,超过15跳就表示不可达。
OSPF协议的最大网络直径为**255**,可以适应更大的网络环境。
##### 4、邻居关系的建立:
RIP**本身并没有邻居关系**的概念,它只会将信息发送给所有直连的且运行RIP协议的所有设备。
OSPF则**有很详尽的邻居**概念,并且根据交互LSA的不同,可以分为邻居(2-way)以及邻接(full)两种不同的邻居关系,前者只会相互发送hello报文,维持邻居关系,而后者则会相互发送路由更新。
##### 5、防环机制:
RIP协议作为典型的距离矢量协议,它的防环机制有两种:**水平分割和毒性逆转**,简单来说,水平分割就是从一个接口接收的路由更新,不会再从该端口发送出去。毒性逆转则是从一个接口接收的路由更新,会再从该接口发出去,但是会将其置为不可达状态(16跳)。
OSPF协议**从算法上就可以达成防环**,请参考第一条...
##### 6、路由传递机制:
RIP协议默认**会进行自动汇总**(有类路由协议),即传输的路由条目会自动进行主类的汇总,这样会导致路由条目不精确,后续RIP协议为了解决该问题,将RIPV1升级为RIPV2,V2版本不仅支持手动汇总,使路由条目传递更加精准,而且将路由更新方式从V1的广播变成了V2的组(224.0.0.9),提升了路由更新效率。
OSPF协议默认**不会进行自动汇总**(无类路由协议),并且会在每个网段的邻居中选举一个DR指定路由器,所有路由更新会通过224.0.0.6发送给DR,DR再通过224.0.0.5发送给其他所有邻居,这样可以防止重复的路由条目更新。
这个点是mark[“RIP协议”与“OSPF协议”的相同点与不同点是什么?](https://www.jianshu.com/p/2898dc090e1d)的,为了方便整理到了一起,大家可以去看看原文。
## 数据链路层
### 如你所想,例子如期而至
夏尔去外地参加比赛了,慕恩打算在他生日那天给他一个惊喜(闪现贴脸)。她可以选择飞机,火车和自行车作为交通工具但最终出发点和目的地都是一致的。
![travel.png](https://user-gold-cdn.xitu.io/2020/4/25/171af953ae721119?w=646&h=482&f=png&s=88475)
链路层的不同链路就像连接两地的路线,链路层的作用就是将A地的数据通过链路传输到B地。
### 链路层的特点
1. 封装成帧: 将网络层的数据报封装为多个数据帧(由一个数据字段和若干首部字段组成)。
2. 链路接入: MAC协议规定了帧在链路上的传输规则。
3. 可靠交互: 类似于传输层的TCP,链路层也能提供可靠的交互。但对于一些低比特差错的链路,如光纤、同轴电缆等,可靠交互被认为时不必要的开销。
4. 差错检测和纠正: 发送方在帧中加入校验位比特,接收方对数据帧进行差错检测和纠正。
### 差错检查和纠正比特
链路层的差错检查和纠正有奇偶校验法,校验和法,CRC编码法。
#### 奇偶校验法
奇偶校验法的思路很简单,就是在数据帧中增加一个比特位使数据帧为奇数称为奇校验,为偶数称为偶校验。接收方接收到数据后只需检测数据帧为奇数还是偶数。但显然这样简单的做法会带来一些问题,虽然同一数据帧多个比特位都被噪声干扰产生比特变化的概率很低,但这样的情况一旦发生了,该差错检验方法就没有起到作用。同时奇偶校验法只能检测差错而不能纠正错误。
#### 校验和法
与之前传输层差错检验的方法基本一致。
#### 循环冗杂检测(CRC)编码
1. 发送方和接收方协商一个r+1比特模式,称为生成多项式,我们将其表示为G
2. 对于一个给定的数据段D,发送方要选择r个附加比特R,并将它们附加到D上,使之得到的d+r模式用模2运算恰好能被G整除。
3. 接收方用G去除接收到的d+r比特,如果余数为零则无差错,否则则认为数据出错丢弃该帧。
![CRC.png](https://user-gold-cdn.xitu.io/2020/4/25/171af953b8ad5c1e?w=540&h=179&f=png&s=57222)
### 多路访问链路和协议
#### 点到点传播和广播
我们将链路连接的设备(交换机,路由器,主机等)称为节点。
点对点链路由链路一端的单个发送方和链路另一端的单个接收方组成。
广播链路能让多个发送和接收节点都连接到相同的单一的、共享的广播信道上。(这里的广播跟教室里老师上课的情景很像)
#### 信道划分协议
##### 时分复用
1. 将时间分割为一个或多个时间帧(与前面提到的数据帧不一样),并进一步划分每个时间帧为N个时隙。
2. 为每条链路分配一个时隙
3. 每条链路在分配到的时隙内进行数据传输
![shifen.png](https://user-gold-cdn.xitu.io/2020/4/25/171af953f5f81cfa?w=476&h=144&f=png&s=43262)
##### 频分复用
与时分复用类似,所谓频分复用是把带宽划分为多个信道分配给每条链路,数据在分配好的频率下进行传输。
##### 码分复用
码分复用对每个节点分配一种不同的编码,然后每个节点用它唯一的编码来对它发送的数据进行编码。
#### 随机接入协议
##### 时隙(ALOHA)
1. 当节点有一个新帧要发送时,它等到下一个时隙开始并在该时隙传输整个帧。
2. 如果没有碰撞,该节点成功的传输它的帧
3. 如果有碰撞,则该节点在时隙结束之前检测到这次碰撞,该节点有随机概率p的几率重传该帧。
##### 具有碰撞检测的载波侦听多路访问(CSMA/CD)
1. 适配器从网络层获取数据报,封装成帧后放入设配器缓存。
2. 如果适配器侦听到信道空闲,它开始传输帧。在另一方面,如果适配器监听到信道正在忙,它将等待,直到监听到信道空闲时再开始传输帧。
3. 在传输过程中,适配器监视来自其他使用该广播信道的适配器的信号能量的存在。
4. 如果适配器传输整个帧而未检测到来自其他适配器的信号能量,该适配器就能完成该帧。在另一方面,如果适配器在传输时检测到来自其他适配器的信号能量,它中止传输。
5. 中止传输后,适配器等待一个随机时间量,然后返回步骤2。
#### 轮流协议
##### 轮询协议
轮询类似于一个中介模式,主节点能够检测信道上是否缺乏信号。主节点轮询各个节点,告诉每个节点能够传输帧的最多数量。
##### 令牌传递协议
当一个节点拥有令牌且有数据帧需要传输时,它发送最大数目的帧数,然后将令牌转发给下一个节点。
如果拥有节点的令牌没有数据帧需要传输,那么它会立即将令牌转发给下一个节点。
### 链路层寻址
#### MAC地址
又称LAN地址,物理地址,严格来说是网卡的地址而不是主机的地址。由48个比特位构成,前24位位标志位,后24位为地址为,采用十六进制表示。
#### 地址解析协议(ARP)
接收一个IP地址,返回一个MAC地址(先从缓存找,没有的话再广播),RARP与之功能相反即接收一个MAC地址返回一个IP地址。
#### 以太网
“以太网几乎占据了现有的有限局域网市场,它之于局域网的地位不亚于因特网之于全球联网的地位。”
##### 以太网的结构
![LAN.png](https://user-gold-cdn.xitu.io/2020/4/25/171af953f5f3c166?w=668&h=55&f=png&s=32255)
1. 数据字段: 该字段承载了P数据报。
2. 目的地址: 包含了目的适配器的MAC地址。
3. 源地址: 包含了传输该帧到局域网上的适配器的MAC地址。
4. 类型字段: 允许以太网复用多种网络层协议。
5. CRC字段: 判定接收适配器检测帧中是否引入了差错。
6. 前同步码: 该前同步码的前7个字节的值都是10101010,最后一个字节时10101011。前同步码字段的前7个字节用于唤醒接收适配器,并且将他们的时钟和发送方的时钟同步。
#### 链路层交换机
##### 交换机的特点
1. 自主学习,即插即用。交换机维护了一个交换机表(类似于路由表,只是使用的是MAC地址),初始化时,它会向与之相连的节点进行广播以获取它们的MAC地址,然后当一个节点很久没有接入到链路中时,则从交换机表中删除该MAC地址。
2. 交换拥有过滤和转发的功能,过滤是决定一个帧应该转发到某个接口还是应当将其丢弃的交换机功能;转发是决定一个帧应该被导向哪个接口。
3. 在使用交换机构建的局域网中,不会因为碰撞而浪费带宽,并且不同链路能够以不同的速率运行在不同的媒体上,因此,对于原有的设备与新设备混用,交换机是理想的。
##### 交换机和路由器比较
1. 交换机是第二层的分组交换机,而路由器是第三层的分组交换机。
2. 交换机即插即用
3. 大型交换网络中要求主机和路由器中由大量的ARP表,这将生成可观的ARP流量和处理量。
## 物理层
传输最底层的信号如电信号,光信号等(高低电平分别表示1和0)。
[更多信息](https://juejin.im/post/5d28508f51882569755f4d64)
## 网络安全
### 网络攻击
#### XSS攻击
- 攻击方式
跨站脚本攻击是指恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
- 解决方案
为cookie设置httpOnly属性,对用户的输入进行检查,进行特殊字符过滤
#### CSRF攻击
- 攻击方式
CSRF跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性,你可以这样来理解:
攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。
- 解决方案
使用验证码,检查https头部的refer,使用token
#### 中间人攻击
- 攻击方式
也称浏览器劫持,web劫持。简单来说就是黑客通过各种各样的技术手段,在服务端发送出的HTTP报文与显示屏呈现的WEB页面之间做了一些手脚,纂改网页的部分或全部内容。主要分为网络挟持纂改和终端挟持纂改(比如盗版游戏中植入的一些木马经常会纂改你的浏览器主页)。
[更多信息](https://www.zhuyingda.com/blog/article.html?id=7&origin=gold)
- 解决方案
使用HTTPS协议传输报文,远离不安全的网站。
### 网络安全是什么
1. 报文的机密性:只有发送发和希望的接收方能够理解传输报文的内容
2. 报文完整性:报文在传输的过程中未发生变化或者恶意篡改
3. 运行安全性:几乎所有的机构都有与公共因特网相连接的局域网,这些网络都因此潜在地能够被危及安全
### 密码学
#### 对称加密
##### 对称加密算法
发送方和接收方持有同一把密钥,发送消息和接收消息都使用该密钥。相比非对称加密算法,该算法加密和解密的速度都更快,但由于双方都需要事先直到密钥,因此在传输过程中更容易被捕获,安全性不如非对称。
##### 恺撒密码
大名鼎鼎的**尤利乌斯·恺撒**是古罗马共和国著名的执政官,他的传奇事迹无需概述。我们都知道行军打仗除了兵马粮草之外,情报也是非常重要的,现代战争俨然一副情报战。于是恺撒使用了一种加密方法进行情报加密再让接收方对情报进行解密,我想这也是他能在高卢战场取得重大胜利的原因之一吧。
```
//恺撒密码,在阐述网络分层的例子我们就用到了这种加密方法
a b c d e f g h i j k l m n o p q r s t u v w x y z (26个字母的闭环)
k = 5
i love u
n qtaj z
```
##### 块密码
1. 将数据报文分块
2. 每一块报文由一个T表进行加密处理
3. 将块报文组装起来
![blockS.jpg](https://user-gold-cdn.xitu.io/2020/4/25/171af953f7e2eaa2?w=860&h=516&f=jpeg&s=94498)
##### 流密码
1. 在加密报文之前,发送方生成一个随机比特串k,作为初试向量`c0`,发送给接收方。
2. 发送方将初始数据`m1`与随机向量`c0`亦或后使用密钥进行加密
3. 对于第`i`个数据报,发送方根据`ci = Ks(mi ^ c(i-1))`生成第i个密文块
4. 接收方根据`Ks`进行解密
上述过程中随机生成的比特串是为了标识数据报。因为有一定可能出现相同的数据报,如果不加入随机标识符,那么相同的数据报会采用相同的加密方法,攻击者可能潜在地猜出明文。
#### 非对称加密
##### 非对称加密算法
接收方生成一个公钥和一个私钥,将公钥发送给发送方。发送方通过该公钥对会话进行加密然后发送到接收方,接收方通过私钥进行解密。发送过程中就算被窃取数据,没有服务端的私钥也难以对信息进行解密,因而安全性较高。
##### RSA算法
最常用的非对称加密算法之一
1. 选择两个大素数`p`和`q`,这两个值越大,就越难以破解,而执行加密和解密所用的时间也就越长。
2. 计算 `n = pq`和` z = (p-1)(q-1)`
3. 选择小于n的一个数`e`,且使得`e`和`z`没有(非1的)公因数。(也就是e和z互素)
4. 求一个数`d`,使得 `ed-1` 可以被`z`整除。`ed mod z = 1`(mod 是取余的意思)
5. 接收方使用的外界可用的公钥Key+是一对数`(n,e)`,其私钥Key-是一对数`(n,d)`
- 发送方发送给接收方一个由`m`表示的比特组合数据,且`m m ^ (ed) mod n`
3. 数论中有这样一个结论:如果`p`和`q`是素数,且有`n = pq,z = (p-1)(q-1)`则`x ^ y mod n <=> x ^ (y mod z) mod n `,应用这个结论,对于`x = m,y = ed, m < n`,可得`m ^ ed mod n = m ^ 1 mod = m`
[RSA算法原理(一)](http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html)
[RSA算法原理(二)](http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html)
#### 报文完整性
##### 密码散列函数
校验和算是比较简单的密码散列函数,因此所谓的密码散列函数以`m`作为输入,并计算得到一个称为散列的固定长度的字符串`H(m)`,要求对于任意两个不同的报文`x,y`使得`H(x) != H(y)`
常见的密码散列函数有[MD5加密算法](https://www.cnblogs.com/hjgods/p/3998570.html)
##### 报文鉴别码
1. 发送方生成报文`m`,用`s`级联`m`以生成`m + s`,并计算散列`H(m + s)`。`H(m + s)`被称为报文鉴别码
2. 发送方将报文鉴别码附加到报文`m`上,生成扩展报文`(m,H(m + s))`,并将该扩展报文发送给接收方
3. 接收方收到一个扩展报文`(m,h)`,由于知道`s`,计算出报文鉴别码`H(m + s)`。如果`H(m + s) = h`,那么接收方表示报文没问题。
##### 数字签名
1. 发送方用将初始报文通过散列函数生成扩展报文,然后再用自己的私钥进行数字签名,然后发送给接收方
2. 接收方使用公钥解密得到散列函数,再与维护在本地的散列函数表中的散列函数进行比对,如果匹配,则接收方可以确认报文的完整性以及发送方的可信任性
##### 公钥认证
1. 服务方向CA证书颁发机构申请证书认证
2. 客户方向服务方请求服务,服务方将证书发给客户方
3. 客户方使用本地内置的证书公钥与服务方发送的证书中的公钥进行校对
4. 验证通过后,再商量建立密钥建立的协议版本,加密方式等,详情见SSL。
### 应用场景
#### 应用层
##### token用户认证
- 组成
1. uid(用户唯一标识)
2. time(当前时间的时间戳)
3. sign(签名,token前几位以哈希算法压缩成的一定长度十六进制字符串)
- 特点
1. 服务端无状态化、支持在多个服务间共享
2. 安全,可以防止csrf攻击
3. 完全由应用管理,可以避开同源策略
- 流程
1. 登录
![image](https://user-gold-cdn.xitu.io/2018/1/27/161375750d33b4cd?imageView2/0/w/1280/h/960/format/webp/ignore-error/1)
2. 业务请求
![image](https://user-gold-cdn.xitu.io/2018/1/27/161375750d5aa746?imageView2/0/w/1280/h/960/format/webp/ignore-error/1)
3. token过期,刷新token
![image](https://user-gold-cdn.xitu.io/2018/1/27/161375750d060f97?imageView2/0/w/1280/h/960/format/webp/ignore-error/1)
#### SSL -让TCP更加安全
SSL被称为安全套接字层,SSL版本3的一个稍加修改的版本被称为运输层安全性(TLS)。
之前谈到HTTPS协议的安全性时提到了SSL,这里复述一下吧:
##### ssl握手过程
1. 客户端向服务端发出加密通信的请求。这被叫做clientHello请求,
- 包括支持的协议版本,一个随机数用于等会生成会话密钥,支持的加密方法,支持的压缩方法
2. 回应,serverhello,
- 确认加密通信协议的版本,一个随机数用于稍后生成会话密钥,确定加密方法,服务器的证书
3. 客户端验证服务端证书是否为可信机构颁步,如果不可信会给访问者一个警告有起决定是否继续通信,
- 返回一个随机数用于公钥加密,编码改变通知(之后的信息都用双方商定的加密方法和密钥发生),客户端握手结束的通知
4. 服务端收到客户端的第三个随机数后,计算生成本次会话用的“会话密钥”,然后向客户端发送下面信息:
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。
[更多信息](https://imququ.com/post/optimize-tls-handshake.html)
#### 网络层
##### IPsec
IPsec有两种不同的分组形式,一种是隧道模式,一种是运输模式。更为蛇和VPN的隧道模式比运输模式部署得更为广泛。
![IPsec.jpg](https://user-gold-cdn.xitu.io/2020/4/25/171af9542448b7a9?w=893&h=330&f=jpeg&s=54648)
1. 在初始IPv4数据报后面附上一个“ESP尾部”字段
2. 使用算法和由SA规定的密钥加密该结果
3. 在这个加密量的前面附加上一个称为“ESP首部”的字段
4. 使用算法和由SA规定的密钥生成一个覆盖整个enchilada的报文鉴别码
5. 该报文鉴别码附加到enchilada的后面形成载荷
6. 生成一个具有经典IPv4首部字段的全新IP首部,该新首部附加到载荷之前
[更多信息](https://blog.csdn.net/NEUChords/articlehttps://img.qb5200.com/download-x/details/92968314?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1)
#### 防火墙的工作是什么
linux操作系统中常见的防火墙有iptables和firewall,作为一枚小白在部署代码时在这上面可是吃尽了苦头,那么防火墙到底有什么不可或缺的理由让我们痛并快乐着呢?
##### 传统分组过滤器
分组过滤器独立地检擦每个数据报,然后基于管理员特定的规则决定该数据包应当允许通过还是应当丢弃。过滤决定取决于下列因素:
- IP源或目的地址
- 在IP数据报中的协议类型字段如TCP,UDP,ICMP
- TCP或UDP的源和目的端口
- TCP标志比特:SYN、ACK
- ICMP报文类型
- 数据报离开和进入网络的不同规则
- 对不同路由器接口的不同规则
##### 状态过滤器
状态过滤器通过用一张连接表来跟踪所有进行中的TCP连接,再维护一张访问控制列表来实现访问过滤。
![table.jpg](https://user-gold-cdn.xitu.io/2020/4/25/171af9543d248dd8?w=1057&h=486&f=jpeg&s=114416)
(图37,选自计算机网络 自顶向下方法)
##### 应用程序网关
一个应用程序网关是一个应用程序特定的服务器,所有应用程序数据都必须通过它。多个应用程序网关可以在同一主机上运行,但是每一个网关都是由自己的进程的单独服务器。
## 最后
感谢你阅读到这里,由于笔者能力有限,不可能面面俱到,文章中可能有错误的或讲解不清晰的地方,希望您能指出,我会尽快地进行处理。如果本文对你有所帮助的话,希望能帮忙点赞收藏一下,你的支持是我前进的动力。
![thanks](https://user-gold-cdn.xitu.io/2020/4/25/171af95454f6ee81?w=650&h=400&f=jpeg&s=55927)
## 参考文献
计算机网络 自顶向下方法 第6版
[两张动图-彻底明白TCP的三次握手与四次挥手](https://blog.csdn.net/qzcsu/articlehttps://img.qb5200.com/download-x/details/72861891)
[“RIP协议”与“OSPF协议”的相同点与不同点是什么?](https://www.jianshu.com/p/2898dc090e1d)
[计算机网络 - 物理层笔记](https://juejin.im/post/5d28508f51882569755f4d64)
[RSA算法原理(一)](http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html)
[RSA算法原理(二)](http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html)
[MD5加密算法](https://www.cnblogs.com/hjgods/p/3998570.html)
[Token 认证的来龙去脉](https://juejin.im/post/5a6c60166fb9a01caf37a5e5)
[IPsec介绍](https://blog.csdn.net/NEUChords/articlehttps://img.qb5200.com/download-x/details/92968314?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1)
[web中间人攻击的威胁](https://www.zhuyingda.com/blog/article.html?id=7&origin=gold)
[TLS 握手优化详解](https://imququ.com/post/optimize-tls-handshake.html)
[[计算机网络] DNS何时使用TCP协议,何时使用UDP协议](https://www.cnblogs.com/lca1826/p/6599269.html)
[面试官多次问我TCP粘包,而我为何屡屡受挫?](https://juejin.im/post/5e6c8ac86fb9a07c9110305d#heading-4)
[Socket 中粘包问题浅析及其解决方案](http://www.hchstudio.cn/article/2018https://img.qb5200.com/download-x/d5b3/)
[(建议收藏)TCP协议灵魂之问,巩固你的网路底层基础](https://juejin.im/post/5e527c58e51d4526c654bf41#heading-4)
加载全部内容