计算机网络

以下多数来自《TCP/IP 详解 卷1:协议》及《计算机网络 自顶向下方法》

TCP 那块很乱,看这篇

HTTPS 那块不知道说对了没有。。。

基本概念

HTTP 或者 DNS 协议封包的时候,在其上层已经封装了 TCP 协议,TCP 协议封装中包含了对应的目的端口和源端口,TCP 之前又封装了 IP 协议,IP 协议中包含了源 IP 地址和目的 IP 地址,以此类推…

基本分层

重点主要是 TCP/IP 协议栈

  • TCP/IP 协议体系的认知
  • 物理层( 比特 bit )
  • 数据链路层( 帧 frame )
    • 以太网帧的格式
    • MTU 的概念
    • ARP 协议、RARP 协议( ARP 查询原理、ARP 缓存 )
  • 网络层( 数据报 datagram )
    • IP 分片:IP 首部格式,如 16 位分片标识、DF 不分片标志、MF 更多分片标志、13 位片偏移、8 位生存时间TTL、16 位首部校验和等等
    • IP 选路 大概是路由表
    • ICMP 协议,报文格式、报文的两大分类:查询和差错、2 种查询报文 + 5 种差错报文
  • 传输层( 报文段 segment )
    • UDP 协议:特点 + 首部各个字段
    • TCP 协议:特点 + 首部字段 + 可靠机制
    • TCP 连接控制:三次握手、四次挥手、同时打开、同时关闭、半关闭
    • TCP 流量控制机制:滑动窗口、慢启动、拥塞避免、快速重传、快速恢复
    • TCP 超时重传机制:各种定时器( 4 个 )
    • 以上大部分隐藏封装于内核中
  • 应用层( 报文 message )
    • DNS 协议:名字空间、DNS 指针查询( 反向查找或逆向解析 )基本原理、DNS 缓存
    • FTP 协议:两条连接(控制连接+数据连接)、两种工作模式( PASV + PORT )、各种 FTP 指令和响应码、FTP 断点续传、匿名 FTP
    • HTTP 协议:报文格式(请求报文、响应报文、请求头各种字段、响应头各种字段)、HTTP 状态码
    • HTTPS 协议:https 的详细握手过程、摘要算法、数字签名、数字证书的原理和过程

DNS

DNS 名称空间

DNS 中使用的所有的名称集合构成了 DNS 名称空间( name space )

这个名称空间和计算机系统的文件夹和文件类似,都是划分为层次且 大小写不敏感 的。整个 DNS 域结构称为 DNS 命名空间

域名结构是树状结构,树的最顶端代表根服务器,根的下一层就是由我们所熟知的 .com、.net、.cn 等通用域和 .cn、.uk 等国家域组成,称为顶级域。网上注册的域名基本都是二级域名,比如 http://baidu.comhttp://taobao.com 等等二级域名,它们基本上是归企业和运维人员管理。接下来是三级或者四级域名

DNS 缓存

一条域名的 DNS 记录会在本地有两种缓存:浏览器缓存 和 操作系统( OS )缓存

在浏览器中访问的时候,会优先访问浏览器缓存,如果未命中则访问 OS 缓存,最后再访问 DNS 服务器

DNS 记录会有一个 TTL

  • OS 缓存会参考 TTL 值,但是不完全等于 TTL 值
  • 而浏览器 DNS 缓存的时间跟 TTL 值无关,每种浏览器都使用一个固定值

缓存同时适用于成功的解析和不成功的解析( 称为否定缓存( negative caching ))

  • 如果一个特定域名的请求无法返回一个记录,该事实也会被缓存
  • 当一再请求不存在的域名时,就能帮助降低互联网流量

反向 DNS 查询

建议“每个可访问 Internet 的主机都应该有一个名称”,并且“对于每个 IP 地址,应该有一个匹配的 PTR 记录”,但这不是 Internet 标准的要求,并非所有 IP 地址都有反向条目

DNS 服务器里有 两个区域,即“正向查找区域”和“反向查找区域”

反向查找区域 即是这里所说的 IP 反向解析,它的作用就是通过查询 IP 地址的 PTR 记录 来得到该 IP 地址 指向的域名( 要成功得到域名就 必需要有该 IP 地址的 PTR 记录 )

消息格式
消息格式

DNS 消息格式有一个固定的 12 字节头部。通常在 UDP/IPv4 传输,且限制于 512 字节( 特殊的可扩展 )

DNS 消息以固定的 12 字节头部开始,随后跟着 4 个 可变长度 的区段( section ):

  • 查询( 或区域 )、回答、授权记录和额外记录
  • 除了第一个区段,其他都包含一个或多个 资源记录(Resource Record, RR)

查询区段 包含一个数据项,结构和 RR 相近,而 RR 可以被缓存,问题不可以

反向 DNS 查询需要的 PTR 就在 RR 中

DNS-PTR.jpg

PTR RR 类型以一种特殊的方式使用了 特殊的域in-addr.arpa( IPv6 中为 ip6.arpa )域。考虑一个 IPv4 地址,128.32.112.208,这个地址来自 128.32 的B类地址空间

为了确定对应到这个地址的名称,首先将该地址 反转,然后添加 特殊的域

1
208.112.32.128.in-addr.arpa.

进行 PTR 记录的查询,实际上是在查询 域 208.112.32.128.in-addr.arpa. 中的 “主机” 208

例子参考 《TCP/IP 详解 卷1:协议》P381

参考文章百度百科阿里cnblogs

“那么IP反向解析是怎么被应用到邮件服务器中来阻拦垃圾邮件的呢?我们来看看下面一个例子:

某天,阿Q到A公司拜访,他递上一张名片,名片上写着他来自“黑道杀人俱乐部”以及电话号码等信息,A公司觉得应该对阿Q的来历做个简单调查,于是打电话到阿Q名片上的电话号码所属电信局进行查实,如果电信局告诉A公司其电话号码不属于“黑道杀人俱乐部”,则A公司将拒绝阿Q的拜访,如果其电话号码的确属于“黑道杀人俱乐部”,A公司可能接受阿Q的拜访也可能进一步查实,于是就打电话到“黑道杀人俱乐部”所属注册机构查询,如果得到的答复确认该俱乐部确有此电话号码,则A公司将接受阿Q的拜访,否则仍将拒绝阿Q的拜访。

这个例子中,阿Q好比是我们的邮件服务器,A公司是对方邮件服务器,“黑道杀人俱乐部”就是我们邮件服务器与对方邮件服务器通信时所使用的HELO域名(不是邮件地址@后的域名),名片上的电话号码就是我们邮件服务器出口的公网IP地址。A公司对阿Q进行调查的过程就相当于一个反向解析验证过程。由此看出,反向解析验证其实是对方服务器在进行的,如果我们没有做反向解析,那么对方服务器的反向解析验证就会失败,这样对方服务器就会以我们是不明发送方而拒收我们发往的邮件,这也就是我们排除其它原因后(如被对方列入黑名单、没有MX记录、使用的是动态IP地址等等)在没做反向解析时无法向sina.com、homail.com发信的原因。”


FTP

FTP:文件传输协议

用户首先提供远程主机的主机名,使本地主机的 FTP 客户端进程建立一个到远程主机 FTP 服务器进程的 TCP 连接

该用户接着提供用户标识和口令,作为 FTP 命令的一部分在该 TCP 连接上传送

一旦该服务器向该用户授权,用户就可以将存放在本地文件系统中的一个或者多个文件复制到远程文件系统( 反之亦然 )

FTP 有状态!

控制端口是 21,数据端口可能是 20,port 是 20,pasv 需要客户端服务端商定

两条连接

FTP使用了两条并行的 TCP 连接 来传输文件

一个是控制连接,一个是数据连接

  • 控制连接 用于在两主机之间 传输控制信息,如用户标识、口令、改变远程目录的命令以及“存放( put )”和“获取( get )”文件的命令
  • 数据连接 用于 实际发送文件

也称 FTP控制信息带外 ( out-of-band )传送的

HTTP 是在传输文件的 同一个 TCP 发送请求和响应首部行的,因此 HTTP 是 带内 ( in-band )发送控制信息的

建立过程

当用户主机与远程主机开始一个 FTP会话 时,FTP 的 客户端 首先与 服务器( 21 号端口 ) 发起一个 用于控制TCP 连接

  • 客户端通过 该控制连接发送命令 ( 用户的标识、口令和改变远程目录 )

当 FTP 的服务端从该连接上 收到 一个文件传输的命令后( 无论是发向还是来自远程主机 ),就 发起 一个到客户端的 TCP数据连接

  • FTP 在该数据连接上准确地传送一个文件,然后 关闭该连接

!!!如果 还需要传输 另一个文件,FTP就 打开另一个 数据连接

!!!因此对FTP来说,控制连接 贯穿了整个用户会话期间,但是对会话中的每一次文件传输都需要建立 一个新的数据连接 ( 即数据连接是非持续性的 )

FTP 服务器 必须在整个会话期间 保留用户的状态 ( state )

  • 服务器必须把 **特定的 **用户账户 与 控制连接 联系起来,随着用户在远程目录树上徘徊,服务器必须追踪用户在远程目录树上的当前位置。对每个进行中的用户会话的状态信息进行追踪,大大限制了 FTP 同时维持的会话总数
  • 而HTTP是 无状态 的,即不必对任何用户状态进行追踪

两种工作模式( PASV + PORT )

百度百科

FTP 支持两种模式,一种方式叫做 Standard ( 也就是 PORT 方式,主动方式 ),一种是 Passive ( 也就是 PASV,被动方式 )

  • Port
    • FTP 客户端 首先和 FTP 服务器TCP 20 端口 建立连接,通过这个通道发送命令,客户端 需要接收数据的时候在这个通道上 发送 PORT 命令
    • PORT 命令包含了客户端用什么端口接收数据。在传送数据的时候,服务器端 通过自己的 TCP 20 端口 连接至 客户端指定端口 发送数据
  • Passive
    • 在建立控制通道的时候和 Port 模式类似,但建立连接后发送的不是 Port 命令,而是 Pasv 命令
    • FTP 服务器 收到 Pasv 命令后,随机 打开一个高端端口( 端口号 大于 1024 ),并且 通知客户端 在这个端口上传送数据的请求,客户端连接 FTP 服务器此端口,通过 三次握手 建立通道,然后 FTP 服务器将通过 这个端口 进行数据的传送

总的来说,主动就是客户端给出端口号让服务端主动来连,被动就是服务端打开端口号让客户端来连

主被动是针对服务端来说的

很多防火墙在设置的时候都是不允许接受外部发起的连接的,所以许多位于防火墙后或内网的 FTP 服务器不支持 PASV 模式,因为客户端无法穿过防火墙打开 FTP 服务器的高端端口

而许多内网的客户端不能用 PORT 模式登陆 FTP 服务器,因为从服务器的 TCP 20 端口无法和内部网络的客户端建立一个新的连接,造成无法工作

选择用PASV方式还是PORT方式登录FTP服务器,选择权在FTP客户端,而不是在FTP服务器。

一、客户端只有内网IP,没有公网IP

从上面的FTP基础知识可知,如果用PORT方式,因为客户端没有公网IP,FTP将无法连接客户端建立数据链路。因此,在这种情况下,客户端必须要用PASV方式,才能连接FTP服务器。大部分FTP站长发现自己的服务器有人能登录上,有人登录不上,典型的错误原因就是因为客户端没有公网IP,但用了IE作为FTP客户端来登录(IE默认使用PORT方式)。

作为FTP站长,有必要掌握FTP的基础知识,然后指导您的朋友如何正确登录您的FTP。

二、客户端有公网IP,但安装了防火墙

如果用PASV方式登录FTP服务器,因为建立数据链路的时候,是由客户端向服务器发送连接请求,没有问题。反过来,如果用PORT方式登录FTP服务器,因为建立数据链路的时候,是由服务器向客户端发送连接请求,此时连接请求会被防火墙拦截。如果要用PORT方式登录FTP服务器,请在防火墙上打开1024以上的高端端口。

https://developer.aliyun.com/article/234007

FTP指令和响应码

为了区分连续的命令,每个命令后跟 回车换行符

每个命令由 4 个大写字母ASCII字符组成

  • USER username:用于向服务器发送用户标识。user
  • PASS password:用户口令。pass
  • LIST:用于请求服务器回送当前远程目录中的所有文件列表。这个列表是数据连接传送的。list
  • RETR filename:检索( 即 get )文件。该命令引起远程主机发起一个数据连接。retr
  • STOR filename:存放( 即 put )文件。stor
  • put 或 send:上传
  • mput:批量上传
  • get 或 recv:下载
  • mget:批量下载
  • size:查看服务器端已接收文件的大小
  • restart:设置断点位置( 已接收文件的大小 )

响应码

  • 331 Username OK,Password required
  • 125 Data connection already open; transfer starting
  • 425 Can’t open data connection
  • 452 Error writing file

详细

FTP 传输模式

ASCII / 二进制

  • 使用 TYPE 命令设置

FTP断点续传

使用 REST 命令

参考

最重要的一点,断点续传 需要服务器的支持,这个是必要条件

其次,客户端要知道使用 REST 等一系列指令来作断点续传

下载:

  • 首先使用 TYPE I 命令告诉 FTP 服务器使用 BINARY ( 二进制 )模式传送文件
  • 然后使用 PASV 命令告诉 FTP 服务器 使用 被动打开 模式来传送文件
  • 接着使用 REST 187392 指令告诉 FTP服务器 文件的 187392 字节 开始 传送( 用 SIZE 获取 )
  • 使用 RETR + 文件名 来下载文件

REST 0 表示从文件 最开始处 下载

上传:

  • APPESTOR,都是追加数据
  • 获取服务器上和本地要上传文件的同名文件大小
  • 向服务器发送 “APPE + 文件名”,通知服务器,接下来从数据通道发送给你的数据要附加到这个文件末尾
  • 定位本地文件指针
  • 从文件指针处读数据并发送( restart )

匿名FTP

只适用于那些 提供了这项服务的主机

百度百科

匿名 FTP 的机制:用户可通过它连接到远程主机上,并从其下载文件,而 无需成为其注册用户

系统管理员建立了一个特殊的用户 ID,名为 anonymous, Internet 上的任何人在任何地方都可使用该用户 ID

通过 FTP 程序连接匿名 FTP 主机的方式同连接普通 FTP 主机的方式差不多,只是在要求提供用户标识 ID 时 必须输入 anonymous(/əˈnɑː.nə.məs/),该用户 ID 的 口令( pass ) 可以是 任意的字符串

一般用自己的 E-mail地址 作为口令,使系统维护程序能够记录下来谁在存取这些文件

匿名 FTP 不适用于所有 Internet 主机,它只适用于那些 提供了这项服务的主机


关羽跨域

https://www.ruanyifeng.com/blog/2016/04/cors.html

HTTP

超文本传输协议

B/S、请求/响应

传输的类型由 Content-Type 决定

无连接

  • 服务器处理完请求,并收到客户的应答后,即断开连接
    • 为了保持会话连接,有了 Cookie 和 Session

无状态

  • 不保留之前的状态

URI 和 URL

  • URI 是标识符( Identifier )
  • URL 是定位符( Location )

参考文章

https://www.zhihu.com/question/21950864/answer/154309494

报文格式

参考文章

https://www.jianshu.com/p/eb3e5ec98a66

( 请求报文、响应报文、请求头各种字段、响应头各种字段 )

通用首部字段
  • Connection: close ( 搞完就关闭连接 )/ keep-alive
    • HTTP/1.1 默认都是持久连接,使用 close 后会明确断开连接
    • HTTP/1.1 之前的版本默认都是非持久连接,使用 keep-alive 可以维持持久连接
  • Transfer-Encoding:传输报文主体时采用的编码方式
通用缓存首部字段
  • Cache-Control:管理缓存信息,HTTP/1.1引入
请求报文
  • 请求行( 第一行 ):包括请求方法、URL、协议/版本( 三者之间用空格分隔 )
  • 请求头( Request Header )
    • Host:服务器的主机名和端口号
    • 其他
  • 空行
  • 请求正文
请求方法
  • GET( 数据放 url 后面,且有长度限制,具体由浏览器决定 )
  • POST( 比 GET 多了 body,没有长度限制 )
  • PUT、DELETE……
  • HEAD:类似 GET,只返回响应报头,不返回响应主体
响应报文
  • 状态行:HTTP 版本、状态码、原因短语
  • 响应头
    • Location:客户端应重定向到指定 URI,基本配合 3** 响应出现
    • Server:HTTP 服务器的应用程序信息
  • 空行
  • 响应正文
实体首部字段

实体首部字段是在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息

  • Content-Encoding 告诉客户端实体的主体部分选用的内容编码方式
  • Content-Language 告诉客户端实体主体使用的自然语言( 中文、英文等 )
  • Content-Length 表明实体主体部分的大小( 单位:字节 )。对实体主体进行内容编码传输时,不能再使用该首部字段
  • Content-Type 响应报文中对象的媒体类型

HTTP 状态码

  • 1XX- 信息型,服务器收到请求,需要请求者继续操作
  • 2XX- 成功型,请求成功收到,理解并处理
  • 3XX - 重定向,需要进一步的操作以完成请求
  • 4XX - 客户端错误,请求包含语法错误或无法完成请求
  • 5XX - 服务器错误,服务器在处理请求的过程中发生了错误
常见
  • 200 OK - 客户端请求成功
  • 301 - 永久性重定向。资源( 网页等 )被永久转移到其它 URL
  • 302 - 临时跳转,常见应用场景是通过 302 跳转将所有的 HTTP 流量重定向到 HTTPS
  • 303:和 302 有着相同的功能,但是 303 明确要求客户端应该采用 GET 方法获取资源
  • 400 Bad Request - 客户端请求有语法错误,不能被服务器所理解
  • 401 Unauthorized - 未认证(没有登录)请求未经授权,这个状态代码和 请求报头 Authorization、响应报头 WWW-Authenticate 一起使用
  • 403 Forbidden:没有权限(登录了但没有权限)
  • 404 - 请求资源不存在,可能是输入了错误的 URL
  • 500 - 服务器内部发生了不可预期的错误
  • 503 Server Unavailable - 服务器当前不能处理客户端的请求,一段时间后可能恢复正常

HTTPS

非对称加密

加密、解密使用不同的密钥

一把作为公开的公钥,另一把作为私钥

公钥加密的信息,只有私钥才能解密

反之,私钥加密的信息,只有公钥才能解密

缺点:加密和解密花费时间长、速度慢,只适合对少量数据进行加密

基本介绍

HTTPS 简单来说就是 非对称加密 + 对称加密

实现的具体步骤
  • 某网站拥有用于非对称加密的公钥 A、私钥 A’
  • 浏览器向网站服务器请求,服务器把公钥 A 传输给浏览器
  • 浏览器随机生成一个用于对称加密的密钥 X,用公钥 A 加密后传给服务器
  • 服务器拿到后用私钥 A’ 解密得到密钥 X
  • 这样双方就都拥有密钥 X 了,且别人无法知道它
  • 之后双方所有数据都用密钥 X 加密解密

非对称加密的是证书的数据( 非对称更适合用于认证对方的合法性 ),对称加密的是实际传输的数据

如何证明浏览器收到的公钥一定是该网站的公钥?

  • 使用数字证书

对于为什么不用CA证书的公钥:

  • CA证书公钥只为了浏览器解密证书验证真伪。不用于加密数据。加密数据使用协商的加密算法
CA 证书
  • CA 生成 明文数字证书,然后将 明文数字证书 运行 Hash 算法,生成 Message Digest,用 CA 的私钥加密 Message Digest,生成 数字签名( Digital Signature ),这样 明文数字证书 + 数字签名 就是用户拿到的 数字证书( Certificate )
  • 客户端/个体得到 明文数字证书 + 数字签名,然后将 明文数字证书 运行相同的 Hash 算法,得到本地的 Message Digest ( A )
  • 客户端/个体用 CA 公钥解开在服务端被私钥加密过的 数字签名,得到绝对正确的 Message Digest ( B )
  • 比较 A 和 B,如果一样,那就安全可信,认证通过
  • 详细说明

详细握手过程

参考文章

两张图解释清楚

  • 上面的是 RSA 加密,下面的是 DH 加密

image-20201226211852324

image-20201226212830332


访问 百度,通过 大白鲨 wireshark 抓包( 下面用的是 DH ):
SSL和TLS2

Client Hello
  • 一个客户端可用的版本号( 版本是向下兼容的 )
  • 一个随机数
  • 一个加密套件( 客户端支持的所有的加密套件,在这里包含 16 个 )
    SSL和TLS3
Server Hello
  • 一个版本号( 版本向下兼容 )

  • 一个随机数

  • 一个从客户端发送的加密套件中选用的双方都支持的加密套件

    • 选用不同的套件会对后续的交互产生不一样的动作

    SSL和TLS4

此时客户端和服务端就已经协商好了版本号,密码套件,并且客户端和服务端都拥有了两个随机数

Server Certificate

服务端会立刻发送一个 Server Certificate 信息,该信息包含了一个很重要的东西:CA 证书,即数字证书

SSL和TLS5

Certificates -> [CA 证书](#CA 证书),包括 明文数字证书 + 数字签名,还有服务器公钥

证书的作用:

  • 一个是身份验证
  • 一个是证书中包含服务器的公钥( 不关 CA 的事 ),该公钥结合密码套件的密钥协商算法协商出预备主密钥 pre-master
Server Key Exchange

该消息是有条件才发送的,刚刚在 [Server Hello](#Server Hello) 中说的,选择不同的密码套件会有不同的动作产生,该信息的发送就是属于不同的动作

它发送的条件是,如果证书包含的信息不足以进行密钥交换,那么必须发送该信息。通常协商的加密套件属于下面的类型,就会发送:

  • DHE_DSS
  • DHE_RSA
  • ECDHE_ECDSA
  • ECDHE_RSA

之前协商的密码套件就是 ECDHE_RSA:

SSL和TLS6

所以这里我们可以看到该信息的发送,并且该信息是紧跟着 Server Certificate 信息的

SSL和TLS7

RSA 与 DH

  • 加密:RSA/DH

  • 身份验证/数字签名:RSA

最上面的时序图中展示的密钥协商方式就是 RSA,该方式较为简单:

  • 客户端生成一个随机数作为 pre-master
  • 从证书中获取服务端的 RSA 公钥,加密 pre-master,传给服务端
  • 服务端使用自己的 RSA 私钥解密,得到 pre-master

由于传递时,pre-master 经过 RSA 公钥加密,只有掌握着 RSA 私钥的服务端才能解开获得内容,满足密钥协商的条件

与RSA方式中 pre-master 完全由客户端生成不同,在DH算法中,pre-master 是客户端和服务器端共同计算出来的,只有经过消息互换才能计算出预备主密钥,流程如下:

  • 服务端内部:生成 DH 参数和 DH 密钥对
  • 服务端( [Server Key Exchange](#Server Key Exchange) )发送给客户端
    • 用自己的 RSA 私钥、签名、DH 参数 和 DH 公钥,最后将签名值、DH 参数、DH 公钥全部发送给客户端
  • 客户端内部:使用服务器 RSA 的公钥( 从证书获取 )校验签名,确保获取到的 DH 参数和 DH 公钥是由服务端签发的
  • 客户端( [Client Key Exchange](#Client Key Exchange) )发送给服务端
    • 通过 DH 参数生成客户端的 DH 密钥对,并将客户端 DH 公钥发送给服务端
  • 客户端( [Change Cipher Spec](#Change Cipher Spec) )告知服务端准备好了
    • 通过客户端DH私钥和服务器端 DH 公钥计算出预备主密钥,并告知服务端准备好了
  • 服务端内部:接收到客户端的 DH 公钥,结合服务器的 DH 私钥计算出预备主密钥 pre-master
  • 最终客户端和服务器端计算出的预备主密钥 pre-master 能够保持一致

客户端每次连接服务器的时候,服务器都会发送动态 DH 信息( DH 参数和 DH 公钥,DH 公钥并不是证书上的那个公钥 ),这些信息不存在证书中,需要通过 [Server Key Exchange](Server Key Exchange) 来进行信息传递,并且传递的 DH 信息需要使用服务器的私钥进行签名

DH 公钥就是 Pubkey,签名就是 Signatrue,DH 参数由 Curve Type、Named Curve、Pubkey 组成的

该信息是用于密钥交换

HTTPS 在真正的通信阶段,是通过对称加密来对内容进行加密的,那么对称加密的密钥交换的安全性就显得非常重要,如果安全的保证客户端和服务端都能获得这个对称加密的密钥就是该信息需要做的事情了

Server Hello Done

SSL和TLS8

服务器发送完上述信息之后,会立刻发送该信息,然后等到客户端的响应

接下来可以和客户端一起协商出预备主密钥

Client Key Exchange

一般有两种方式:

  • 客户端通过 RSA/ECDSA 算法加密预备主密钥,然后发送给服务器
  • 通过服务器发送的 DH 参数计算出客户端的 DH 公钥,并传递给服务器
  • 这里使用的是第二种方式

SSL和TLS9

Change Cipher Spec

该信息用于告诉对方,我已经计算好需要使用的对称密钥了,我们接下来的通信都需要使用该密钥进行加密之后再发送

SSL和TLS10

Encrypted Handshake Message

即加密的握手信息
SSL和TLS11


运输层的多路复用和多路分解

  • 将运输层报文段的数据交付到正确的套接字的工作称为 多路分解
  • 在源主机从不同套接字中收集数据块,并为每个数据块封装上首部信息( 这将在以后用于分解 )从而产生报文段,然后将报文段传递到网络层,所有这些工作称为 多路复用

UDP

参考文章

UDP( 用户数据报协议 )

  • 在发送报文段之前,发送方和接收方的运输层实体之间没有握手。所以 UDP 被称为无连接的

  • 无须执行任何与运行在目的端系统中的 UDP 实体之间的握手,主机端的 UDP 为此报文添加首部字段,然后将形成的报文段交给网络层

    • 网络层将此 UDP 报文段封装进一个 IP 数据报中,然后将其发送给一个名字服务器……
  • UDP 首部开销小,仅有 8 字节

UDP首部

UDP首部只有 4 个字段,每个字段由 2 个字节组成,即首部 8 个字节

UDP1

长度字节 -> UDP 报文段中的字节数( 首部 + 数据 )

UDP校验和

把报文段的所有 16 比特字求和( 溢出要回卷 ),然后 取反,得到 校验和( 回卷就是进位加到末位 )

接收方将全部 16 比特之和 + 校验和,若都为 1,就没有出错

特点

  • 提供无连接服务

  • 在传送数据之前不需要先建立连接

  • 传送的数据单位协议是 UDP 报文或用户数据报

  • 对方的运输层在收到 UDP 报文后,不需要给出任何确认

  • 虽然 UDP 不提供可靠交付,但在某些情况下 UDP 是一种最有效的工作方式

  • UDP 支持一对一、一对多、多对一和多对多的交互通信

  • UDP 的首部开销小,只有 8 个字节,比 TCP 的 20 个字节的首部要短

UDP 对应用层交下来的报文,既不合并,也不拆分,而是 保留这些报文的边界

应用层交给 UDP 多长的报文,UDP 就照样发送,即一次发送一个报文

UDP2

TCP

!!!看这篇,下面都很乱,且有错!!!

就是类似“打电话”

  • TCP ( 传输控制协议 ):面向连接

  • TCP 是可靠的

  • 可靠传输、流量控制、避免网络拥塞

  • TCP 连接提供的是 全双工服务:有A到B的一条TCP连接,那么数据能从A到B,也能B到A(同时)。

  • 也是 点对点

  • TCP 是面向字节流的,就是一个文件,TCP 先把数据块拿到 TCP 发送缓存,然后发送到接收方的接收缓存,然后再到文件系统

TCP是如何实现可靠传输的

校验和
序列号
确认应答
超时重传
连接管理
流量控制
拥塞控制
停止等待协议

TCP1

(超时重传在下面)

(RTT:往返时间)

确认丢失和确认迟到

TCP2

总结就是:只要你没告诉我收到,我就认为你没收到,就要重发

使用上述的确认和重传机制,就能在不可靠的传输网络上实现可靠的通信

这种可靠传输协议称为 自动重传请求(Automatic RepeatQuest) (《计算机网络自顶向下》P138)

ARQ

ARQ 表明重传的请求是 自动 进行的。接收方不需要请求发送方重传

TCP3
Td是发的时间,Ta是收的时间,RTT是往返时间,大部分时间在等……

信道利用率:
TCP4

提高信道利用率,因为RTT和Ta几乎不变,就要提高Td,即发送的时间,即数据进入链路的时间:

TCP5
这就是 流水线传输
就不等它确认了,那是怎么保证可靠呢?

GBN (回退N步)协议

连续ARQ协议,也就是 滑动窗口,也称为 GBN (回退N步)协议

TCP6

发送窗口5就是5个可以连续发送
开始等确认,如果1确认
窗口往右移1

TCP7

2确认,右移1,以此类推……已经确定的就能从缓存清掉

但是这样每个数据都要确认,效率还是低
然后就有了 累计确认

TCP8

上面是接收方,下面是发送方

发送方累计确认123后,证明123都收到了,就滑动3个

如果3丢了,4确认了

TCP9

会认为发送方累积确认到2,就会重传3,接收方会丢弃后面的失序分组

丢了又可惜,就有了 SACK(选择确认选项)

SACK

当接收方接收到乱序的数据时,能提供一个SACK来描述

SACK 包含了不连续块的第一个数据的序列号和不连续块的最后一个数据的序列号之后的序列号

TCP报文段首部

TCP10

选项一般为空,使用首部一般为20字节(UDP首部8个)

序号:
因为TCP是面向字节流的,序号就是建立在字节流之上,而不是建立在传送的报文段的序列之上,因此一个报文段的序号是这个报文段首字节的字节流编码

确认号:
因为 全双工,主机A发送的报文段的确认号就是A期望从主机B收到的下一个字节的序号。
假设主机A已经收到了来自B的编号为0-535的所有字节,同时假设A 打算 发一个报文段给B。如果A期望B的字节流中的536及以后的字节,就会在A发往B的报文段的 确认号 中填上 536

数据偏移
4位,1111,十进制15,也就是说选项部分最多40个字节(这里我也不懂是啥意思)
记录TCP报文段的第多少个字节后就是数据,数据偏移 也叫 首部长度

TCP12

TCP13

TCP14

标记位
就是 ACK什么的那些,有这些就能在缓存中不用排队,直接优先
注意:ACK、SYN(三次握手)

PSH 是 push,123发过去,接收方按顺序读123,如果3的标记位PSH 为 1,就是312,就是急着交作业

RST 是 reset,严重错误,需要重新来建立连接

URG urgent,为1时,假设紧急指针为50,就代表TCP数据部分前50(包括50)字节需要紧急处理

窗口
用于指示接收方愿意接受的字节数量,常用于 流量控制

TCP15

MSS 最大报文段长度

TCP连接控制

传输连接有三个阶段:连接建立、数据传输、连接释放

三次握手、四次挥手

三次握手 say hello:
SYN 为 1 代表这是用于连接的报文段,不包含应用层数据
1、客户端发送 SYN 报文段,即 SYN 置为1、ACK 0、序号随机 x (client_isn)、确认号 0
2、服务端收到了 客户端的SYN报文段,发送 SYN 1、确认号 x + 1、ACK 1、序号 y(server_isn)
3、客户端 收到了,发送 ACK 1、确认号 y + 1、SYN 0、序号 x + 1

TCP21
TCP22
SYN_SENT、ESTAB_LISHED
LISTEN、SYN_RCVD(receive)、ESTAB_LISHED

ACK 0 -> 确认号无效
ACK 1 -> 确认号有效

SYN 常被用来 SYN 洪泛攻击,频繁请求会话

四次挥手 say goodbye:

TCP23
TCP24

1、发送方:我要结束了;
2、接收方:好的
3、接收方:我也要关掉了;
4、发送方:好的
即:
1、发送方发送一个FIN,希望接收方看到自己的序号Seq(K),还包含了一个ACK(L)用于确认对方最近一次发来的数据
2、接收方设置响应的ACK为K+1,表明它已经成功收到了发送方主动关闭的FIN,并设置序号Seq(L)
3、接收方再次发送自己的FIN,且序号Seq为L,ACK为K+1
4、发送方为了完成连接的关闭,要发送一个确认,包含ACK (L+1)(确认上一个FIN)、Seq (K)。
如果出现FIN丢失的情况,那么发送方会一直发,直到收到ACK为止

同时打开、同时关闭、半关闭

半关闭 (渣?):
我发送了一个FIN给对方,但是我仍然希望接收对方的数据,直到对方发送一个FIN给我
当第二个FIN被确认后,整个连接才完全关闭。

TCP25

同时打开 and 同时关闭

TCP26

注意:同时打开只是建立一条TCP连接。同时关闭和正常关闭类似,只是顺序是交叉的

TCP实现可靠传输

以字节单位的滑动窗口

就是上面的 TCP实现可靠传输

TCP流量控制机制

就是滑动窗口(连续ARQ),调节 窗口的大小 来控制

参考:https://zhuanlan.zhihu.com/p/37379780

这里如果 死锁 呢?
死锁:当发送者收到了一个窗口为0的应答,发送者便停止发送,等待接收者的下一个应答。但是如果下一个窗口不为0的应答在传输过程丢失,发送者一直等待下去,而接收者以为发送者已经收到该应答,等待接收新数据,这样双方就相互等待,从而产生死锁。
为了避免流量控制引发的死锁,TCP使用了持续计时器。每当发送者收到一个零窗口的应答后就启动该计时器。时间一到便主动发送报文询问接收者的窗口大小。若接收者仍然返回零窗口,则重置该计时器继续等待;若窗口不为0,则表示应答报文丢失了,此时重置发送窗口后开始发送,这样就避免了死锁的产生。

TCP18

TCP超时重传机制

基于计时器的重传(RTO)

TCP发送数据时会设置计时器

设置时间

超时重传的时间应略大于下面得出的加权平均往返时间RTTs

TCP16

推荐的 α 值为 1/8

每个数据包都有相应的计时器,一旦超过 RTO 而没有收到 ACK,就重发该数据包。没收到 ACK 的数据包都会存在重传缓冲区里,等到 ACK 后,就从缓冲区里删除。

快速重传

服务器如果收到乱序的包,也给客户端回复 ACK,只不过是重复的 ACK。收到乱序的包 6,7,8,9 时,服务器全都发 ACK = 5。这样,客户端就知道 5 发生了空缺。一般来说,如果客户端连续三次收到重复的 ACK,就会重传对应包,而不需要等到计时器超时。

但快速重传仍然没有解决:到底该重传多少个包?

带选择确认的重传(SACK)

参考:https://zhuanlan.zhihu.com/p/101702312

在快速重传的基础上,返回最近收到的报文段的序列号范围,这样客户端就知道,哪些数据包已经到达服务器了。
Left Edge,Right Edge 就是这些乱序包的左右边界。

TCP17

拥塞控制

拥塞控制 主要包括:1、慢启动;2、拥塞避免;3、快重传;4、快恢复

MSS:最大报文段长度,典型值就是1460,拨号光纤好像是1440

TCP19
TCP27

假设当前发送方 拥塞窗口cwnd 为1个(拥塞窗口cwnd的值是几,就能发送几个数据报文段,实际上书里就是设置为1个MSS,具体看系统),接收方收到报文段后回复一个确认,发送方首次收到确认后将cwnd设为2,接下来,cwnd 4、8、16……以指数增长,这就是 慢启动

当达到 慢启动阈值 ssthresh 时,TCP会谨慎增加cwnd,即进入 拥塞避免 阶段,每次cwnd增加1,然后分两种版本:

  • 如果发生 超时重传,就 重新进入慢启动,ssthresh设置为cwnd的一半,新的cwnd设置为1(TCP Tahoe版本)

  • 如果 连续有三个冗余的ACK 时,就是出现丢包,就将相应的报文段重传(快速重传),开始执行 快恢复,将ssthresh设置为cwnd的一半,新的cwnd设置为新的ssthresh(TCP Reno版本),然后每次+1。新的cwnd也可以设置为ssthresh + 3

    TCP20

参考:《自顶向下》P186


网络层

  • 负责在不同网络之间尽力转发数据包
  • 基于数据包的 IP 地址转发
  • 不负责丢失重传
  • 不负责顺序

发送数据的过程:

TCP28

IP

IPv4数据报格式:

TCP29

标识、标志、片偏移。和[ IP 分片](#IP 分片) 有关

偏移字段表示:

  • 该分片负载字节中的第一个字节在原始 IPv4 数据中的偏移量( 以 8 字节为单位 )

MF 字段表明:

  • 该数据报后面是否还有更多的分组,只有最后一个才被设置为 0

IP 分片

一个链路层帧能承载的最大数据量叫 最大传输单元(MTU)

最后一个片的标志位 MF 被设置为 0,其他所有片被设置为 1

TCP30


IP 选路

参考文章


ICMP 协议

ICMP(Internet Control Message Protocol:Internet 控制报文协议)用来记录诊断信息

ICMP 报文是在 IP 数据报内被封装的

TCP31
  • 类型字段保留了 42 个不同的值,用于确定特定的报文。只有大概 8 个是经常使用的
  • 许多类型的 ICMP 报文也使用不同的代码字段进一步指定报文的含义
  • 校验和时段覆盖整个 ICMPv4 报文

ICMP 数据报可以分为两大类:

  • 有关 IP 数据报传递的 ICMP 报文( 称为 差错报文 )
  • 有关信息采集和配置的 ICMP 报文( 称为 查询或信息类报文 )

信息类报文包括回显请求( 类型 8 )和回显应答( 类型 0 ),以及路由器通告( 类型 9 )和路由器请求( 类型 10 )( 9 和 10 统称为路由器发现 )

常见的差错报文包括目的不可达( 类型 3 )、重定向( 类型 5 )、超时( 类型 11 )和参数问题( 类型 12 )

TCP32

以太网帧

TCP33 TCP35

FCS( 帧检验序列 )常用 CRC( 循环冗余检验 ) 《协议》P59


PPP 协议

点到点协议

TCP34

PPP里面还包含:

  • 链路控制协议( LCP )
  • 网络控制协议( NCP )
  • 高级数据链路控制协议( HDLC )
  • ……

PPP协议的六个阶段:

  1. 链路不可用阶段: 初始阶段
  2. 链路建立阶段: LCP 协商,( 协商认证方式等 )
  3. 验证阶段: PAP/CHAP 验证
  4. 网络层协议阶段:NCP 协商
  5. PPP 会话维持阶段: 维持 PPP 会话, 定时发送 Echo Request 报文,并等待 Echo Reply 报文
  6. 网络终止阶段: 终止PPP 会话,回到链路不可用阶段

详见:《协议》P89


MTU

以太网的最大传输单元 = 1500字节


ARP协议

ARP:地址解析协议

在 OSI 中,ARP 是属于链路层,在 TCP/IP 中,ARP 属于 网络层。我觉得都有。。。

ARP 几乎用于 IPv4 和以太网 MAC 地址之间的映射,简单说就是能通过 IP 找到 MAC 地址

ARP 正常模式下,仅适用于广播网络

链路层广播:在一个共享的链路层网段上,ARP 向所有主机发送一个称为 ARP 请求 的以太网帧

同一广播域中的所有系统都能接收 ARP 请求

响应一个 ARP 应答,告诉发送 ARP 请求的主机“我的 IP 和 MAC”

  • 这个应答不是广播,而是直接发给发送请求的主机

之后发送方就能将数据报封装在以太网帧中 直接 发给目的主机( 同一域 ),不需要经过路由器

ARP缓存
在内存

RARP:逆向ARP,通过 MAC 能知道 IP,已经很少使用