【网络基础知识5】 --- TCP 协议详解
本文是准备面试过程中网络部分总结整理的最后一篇文章,主要介绍以下知识:
HTTP 协议概述
POST 请求和 GET 请求
Cookie 和 Session
数据传输时的加密
HTTPS 简介
HTTP 协议
在 OSI 七层模型中,HTTP 协议位于最顶层的应用层中。通过浏览器访问网页就直接使用了 HTTP 协议。使用 HTTP 协议时,客户端首先与服务端的 80 端口建立一个 TCP 连接,然后在这个连接的基础上进行请求和应答,以及数据的交换。
HTTP 工作原理
HTTP 有两个常用版本,分别是 1.0 和 1.1。主要区别在于 HTTP 1.0 中每次请求和应答都会使用一个新的 TCP 连接,而从 HTTP 1.1 开始,运行在一个 TCP 连接上发送多个命令和应答。因此大幅度减少了 TCP 连接的建立和断开,提高了效率。
由 HTTP 协议加载出来的网页,通常使用 HTML 语言来描述,因此 HTML 也可以理解为网页的一种数据格式。HTML 是一段纯文本,可以指定网页中的文字、图像、音频视频图片、链接,以及它们的颜色、位置等。无论计算机的底层结构如何,也无论网络底层使用了哪些协议,使用 HTML 展示出来的效果基本上是一致的。从这个角度来说 HTML 位于 OSI 七层模型的表现层。
POST 请求和 GET 请求
HTTP 有八种请求(也称方法),其中最常见的是 GET 请求和 POST 请求。
GET 请求通常用于查询、获取数据,而 POST 请求则用于发送数据,除了用途上的区别,它们还有以下这些不同:
GET 请求可以被缓存,可以被收藏为书签,但 POST 不行。
GET 请求会保留在浏览器的历史记录中,POST 不会。
GET 请求的长度有限制(不同的浏览器不一样,大约在几 Kb 左右),URL 的数据类型只能是 ASCII 字符,POST 请求没有限制。
GET 请求的参数在 URL 中,因此绝不能用 GET 请求传输敏感数据。POST 请求数据则写在 HTTP 的请求头中,安全性略高于 GET 请求。
注意:
POST 请求仅比 GET 请求略安全一点,它的数据不在 URL 中,但依然以明文的形式存放于 HTTP 的请求头中。
Cookie 和 Session
HTTP 是一种无状态的连接,客户端每次读取 web 页面时,服务器都会认为这是一次新的会话。但有时候我们又需要持久保持某些信息,比如登录时的用户名、密码,用户上一次连接时的信息等。这些信息就由 Cookie 和 Session 保存。
这两者的根本性区别在于,cookie 保存在客户端上,而 session 则保存在服务器中。由此我们还可以拓展出以下结论:
cookie 相对来说不安全,浏览器可以分析本地的 cookie 进行 cookie 欺骗。
session 可以设置超时时间,超过这个时间后就失效,以免长期占用服务端内存。
单个 cookie 的大小有限制(4 Kb),每个站点的 cookie 数量一般也有限制(20个)。
客户端每次都会把 cookie 发送到服务端,因此服务端可以知道 cookie,但是客户端不知道 session。
当服务器接收到 cookie 后,会根据 cookie 中的 SessionID 来找到这个客户的 session。如果没有,则会生成一个新的 SessionID 发送给客户端。
加密
加密分为两种,对称加密和非对称加密。在解释这两者的含义前,先来看一下简单的加密、解密过程:
加密和解密过程
所谓的对称,就是指加密秘钥和解密秘钥相同,而非对称自然就是指两者不同。
举一个对称加密的例子。假设这里的加密算法是加法,解密算法是减法。如果明文数据是 10,秘钥是 1,那么加密数据就是10 + 1 = 11
,如果接收方不知道秘钥,就不知道密文 11 应该减去几。反之,如果接收方知道秘钥是 1,就可以通过11 - 1 = 10
计算出明文数据。
常见的一个非对称加密算法是 RSA 算法,它主要利用了“两个素数求乘积容易,但是将乘积分解为两个素数很难”这一思想。它的具体原理不在本文讨论范围,有兴趣的读者可以查看文章末尾的参考文章。
在非对称加密中,利用公钥加密的数据能且只能通过私钥解密,通过私钥加密的数据能且只能通过公钥解密。
对称加密的优点在于速度快,但是假设秘钥由服务器保存,如何安全的让客户端得到秘钥是需要解决的问题。因此实际的网络传输中,通常使用对称加密与非对称加密结合的方式,服务端通过非对称加密将对称秘钥发给客户端。此后双方使用这个对称密钥进行通信。
HTTPS
我们知道 HTTP 协议直接使用了 TCP 协议进行数据传输。由于数据没有加密,都是直接明文传输,所以存在以下三个风险:
窃听风险:第三方节点可以获知通信内容。
篡改风险:第三方节点可以修改通信内容。
冒充风险:第三方节点可以冒充他人身份参与通信。
比如你在手机上打开应用内的网页时,有时会看到网页底部弹出了广告,这实际上就说明你的 HTTP 内容被窃听、并篡改了。
HTTPS 协议旨在解决以上三个风险,因此它可以:
保证所有信息加密传输,无法被第三方窃取。
为信息添加校验机制,如果被第三方恶意破坏,可以检测出来。
配备身份证书,防止第三方伪装参与通信。
HTTPS 的结构如图所示:
HTTPS 协议
可见它仅仅是在 HTTP 和 TCP 之间新增了一个 TLS/SSL 加密层,这也印证了一句名言:“一切计算机问题都可以通过添加中间层解决”。
使用 HTTPS 时,服务端会将自己的证书发送给客户端,其中包含了服务端的公钥。基于非对称加密的传输过程如下:
客户端使用公钥将信息加密,密文发送给服务端
服务端用自己的私钥解密,再将返回数据用私钥加密发回客户端
客户端用公钥解密
这里的证书是服务器证明自己身份的工具,它由权威的证书颁发机构(CA)发给申请者。如果证书是虚假的,或者是自己给自己颁发的证书,服务器就会不认可这个证书并发出警告:
[图片上传中。。。(4)]12306 的自签名证书
总结一下 HTTPS 协议是如何避免前文所说的三大风险的:
先用非对称加密传输密码,然后用这个密码对称加密数据,使得第三方无法获得通信内容
发送方将数据的哈希结果写到数据中,接收方解密后对比数据的哈希结果,如果不一致则说明被修改。由于传输数据加密,第三方无法修改哈希结果。
由权威机构颁发证书,再加上证书校验机制,避免第三方伪装参与通信。
参考文章
HTTPS科普扫盲帖
SSL/TLS协议运行机制的概述
RSA 加密
HTTP 方法:GET 对比 POST
作者:bestswifter链接:http://www.jianshu.com/p/6e7521041e92來源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。本文是准备面试过程中网络部分总结整理的最后一篇文章,主要介绍以下知识:
HTTP 协议概述
POST 请求和 GET 请求
Cookie 和 Session
数据传输时的加密
HTTPS 简介
HTTP 协议
在 OSI 七层模型中,HTTP 协议位于最顶层的应用层中。通过浏览器访问网页就直接使用了 HTTP 协议。使用 HTTP 协议时,客户端首先与服务端的 80 端口建立一个 TCP 连接,然后在这个连接的基础上进行请求和应答,以及数据的交换。
HTTP 工作原理
HTTP 有两个常用版本,分别是 1.0 和 1.1。主要区别在于 HTTP 1.0 中每次请求和应答都会使用一个新的 TCP 连接,而从 HTTP 1.1 开始,运行在一个 TCP 连接上发送多个命令和应答。因此大幅度减少了 TCP 连接的建立和断开,提高了效率。
由 HTTP 协议加载出来的网页,通常使用 HTML 语言来描述,因此 HTML 也可以理解为网页的一种数据格式。HTML 是一段纯文本,可以指定网页中的文字、图像、音频视频图片、链接,以及它们的颜色、位置等。无论计算机的底层结构如何,也无论网络底层使用了哪些协议,使用 HTML 展示出来的效果基本上是一致的。从这个角度来说 HTML 位于 OSI 七层模型的表现层。
POST 请求和 GET 请求
HTTP 有八种请求(也称方法),其中最常见的是 GET 请求和 POST 请求。
GET 请求通常用于查询、获取数据,而 POST 请求则用于发送数据,除了用途上的区别,它们还有以下这些不同:
GET 请求可以被缓存,可以被收藏为书签,但 POST 不行。
GET 请求会保留在浏览器的历史记录中,POST 不会。
GET 请求的长度有限制(不同的浏览器不一样,大约在几 Kb 左右),URL 的数据类型只能是 ASCII 字符,POST 请求没有限制。
GET 请求的参数在 URL 中,因此绝不能用 GET 请求传输敏感数据。POST 请求数据则写在 HTTP 的请求头中,安全性略高于 GET 请求。
注意:
POST 请求仅比 GET 请求略安全一点,它的数据不在 URL 中,但依然以明文的形式存放于 HTTP 的请求头中。
Cookie 和 Session
HTTP 是一种无状态的连接,客户端每次读取 web 页面时,服务器都会认为这是一次新的会话。但有时候我们又需要持久保持某些信息,比如登录时的用户名、密码,用户上一次连接时的信息等。这些信息就由 Cookie 和 Session 保存。
这两者的根本性区别在于,cookie 保存在客户端上,而 session 则保存在服务器中。由此我们还可以拓展出以下结论:
cookie 相对来说不安全,浏览器可以分析本地的 cookie 进行 cookie 欺骗。
session 可以设置超时时间,超过这个时间后就失效,以免长期占用服务端内存。
单个 cookie 的大小有限制(4 Kb),每个站点的 cookie 数量一般也有限制(20个)。
客户端每次都会把 cookie 发送到服务端,因此服务端可以知道 cookie,但是客户端不知道 session。
当服务器接收到 cookie 后,会根据 cookie 中的 SessionID 来找到这个客户的 session。如果没有,则会生成一个新的 SessionID 发送给客户端。
加密
加密分为两种,对称加密和非对称加密。在解释这两者的含义前,先来看一下简单的加密、解密过程:
[图片上传中。。。(2)]加密和解密过程
所谓的对称,就是指加密秘钥和解密秘钥相同,而非对称自然就是指两者不同。
举一个对称加密的例子。假设这里的加密算法是加法,解密算法是减法。如果明文数据是 10,秘钥是 1,那么加密数据就是10 + 1 = 11
,如果接收方不知道秘钥,就不知道密文 11 应该减去几。反之,如果接收方知道秘钥是 1,就可以通过11 - 1 = 10
计算出明文数据。
常见的一个非对称加密算法是 RSA 算法,它主要利用了“两个素数求乘积容易,但是将乘积分解为两个素数很难”这一思想。它的具体原理不在本文讨论范围,有兴趣的读者可以查看文章末尾的参考文章。
在非对称加密中,利用公钥加密的数据能且只能通过私钥解密,通过私钥加密的数据能且只能通过公钥解密。
对称加密的优点在于速度快,但是假设秘钥由服务器保存,如何安全的让客户端得到秘钥是需要解决的问题。因此实际的网络传输中,通常使用对称加密与非对称加密结合的方式,服务端通过非对称加密将对称秘钥发给客户端。此后双方使用这个对称密钥进行通信。
HTTPS
我们知道 HTTP 协议直接使用了 TCP 协议进行数据传输。由于数据没有加密,都是直接明文传输,所以存在以下三个风险:
窃听风险:第三方节点可以获知通信内容。
篡改风险:第三方节点可以修改通信内容。
冒充风险:第三方节点可以冒充他人身份参与通信。
比如你在手机上打开应用内的网页时,有时会看到网页底部弹出了广告,这实际上就说明你的 HTTP 内容被窃听、并篡改了。
HTTPS 协议旨在解决以上三个风险,因此它可以:
保证所有信息加密传输,无法被第三方窃取。
为信息添加校验机制,如果被第三方恶意破坏,可以检测出来。
配备身份证书,防止第三方伪装参与通信。
HTTPS 的结构如图所示:
HTTPS 协议
可见它仅仅是在 HTTP 和 TCP 之间新增了一个 TLS/SSL 加密层,这也印证了一句名言:“一切计算机问题都可以通过添加中间层解决”。
使用 HTTPS 时,服务端会将自己的证书发送给客户端,其中包含了服务端的公钥。基于非对称加密的传输过程如下:
客户端使用公钥将信息加密,密文发送给服务端
服务端用自己的私钥解密,再将返回数据用私钥加密发回客户端
客户端用公钥解密
这里的证书是服务器证明自己身份的工具,它由权威的证书颁发机构(CA)发给申请者。如果证书是虚假的,或者是自己给自己颁发的证书,服务器就会不认可这个证书并发出警告:
12306 的自签名证书
总结一下 HTTPS 协议是如何避免前文所说的三大风险的:
先用非对称加密传输密码,然后用这个密码对称加密数据,使得第三方无法获得通信内容
发送方将数据的哈希结果写到数据中,接收方解密后对比数据的哈希结果,如果不一致则说明被修改。由于传输数据加密,第三方无法修改哈希结果。
由权威机构颁发证书,再加上证书校验机制,避免第三方伪装参与通信。
参考文章
HTTPS科普扫盲帖
SSL/TLS协议运行机制的概述
RSA 加密
HTTP 方法:GET 对比 POST
作者:bestswifter链接:http://www.jianshu.com/p/6e7521041e92來源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。TCP 协议是面向有连接的协议,它具有丢包重发和流量控制的功能,这是它区别于 UDP 协议最大的特点。本文就主要讨论这两个功能。
数据包重发
- 数据发送
丢包重发的前提是发送方能够知道接收方是否成功的接收了消息。所以,在 TCP 协议中,接收端会给发送端返回一个通知,也叫作确认应答(ACK),这表示接收方已经收到了数据包。
根据上一节对 TCP 首部的分析得知,ACK 的值和下次发送数据包的序列号相等。因此 ACK 也可以理解为:“发送方,下次你从这个位置开始发送!”。下图表示了数据发送与确认应答的过程:
ACK 确认
数据包和 ACK 应答都有可能丢失,在这种情况下,发送方如果在一段时间内没有收到 ACK,就会重发数据:
未收到 ACK 时重发数据
即使网络连接正常,由于延迟的存在,接收方也有可能收到重复的数据包,因此接收方通过 TCP 首部中的 SYN 判断这个数据包是否曾经接收过。如果已经接收过,就会丢弃这个包。
- 重传超时时间(RTO)
如果发送方等待一段时间后,还是没有收到 ACK 确认,就会启动超时重传。这个等待的时间被称为重传超时时间(RTO,Retransmission TimeOut)。RTO 的值具体是多久呢?
首先,RTO 的值不是固定的,它是一个动态变化的时间。这个时间总是略大于连接往返时间(RTT,Round Trip Time)。这个设定可以这样理解:“数据发送给对方,再返回到我这里,假设需要 10 秒,那我就等待 12秒,如果超过 12 秒,那估计就是回不来了。”
RTT 是动态变化的,因为谁也不知道网络下一时刻是否拥堵。而当前的 RTO 需要根据未来的 RTT 估算得出。RTO 不能估算太大,否则会多等待太多时间;也不能太小,否则会因为网络突然变慢而将不该重传的数据进行重传。
RTO 有自己的估算公式,可以保证即使 RTT 波动较大,它的变化也不会太剧烈。感兴趣的读者可以自行查阅相关资料。
TCP 窗口
按照之前的理论,在数据包发出后,直至 ACK 确认返回以前,发送端都无法发送数据,而且包的往返时间越长,网络利用效率和通信性能就越低。前两张图片形象的解释了这一点。
为了解决这个问题,TCP 使用了“窗口”这个概念。窗口具有大小,它表示无需等待确认应答就可以继续发送数据包的最大数量。比如窗口大小为 4 时,数据发送的示意图如下:
窗口大小为 4
不等确认就连续发送若干个数据包会不会有问题呢?我们首先来看数据包丢失问题。
我们知道 TCP 首部中的 ACK 字段表示接收方已经收到数据的最后位置。因此,接收方成功接收到了 1-1000 字节的数据后,它会发送一个 ACK = 1001 的确认包。假设 1001-2000 字节的数据包丢失了,由于窗口长度比较大,发送方会继续发送 2001-3000 字节的数据包。接收端并不会返回这个数据包的确认,因为它最后收到的数据还是 1-1000 字节的数据包。
因此,接收端返回的数据包的 ACK 依然是 1001。这表示:“喂,发数据的,别往后发了,你第 1001 字节开始的数据还没来呢”。可以想见,发送端以后每次发送数据包得到的确认中,ACK 的值都是 1001。当连续收到三次确认之后,发送方会意识到:“对方还没有接收到数据,这个包需要重传”。
因此,引入窗口的概念后,被发送的数据不能立刻丢弃,需要缓存起来以备将来需要重发。
利用窗口发送数据的过程可以用下图表示:
快速重传
如果是数据包没有丢失,但是确认包丢失了呢?这就是窗口最擅长处理的问题了。假设发送发收到的确认包中的 ACK 第一次是 1001,第二次是 4001。那么我们完全可以相信中间的两个包是成功被接收的。因为如果有没接收到的包,接收方是不会增加 ACK 的。
在这种情况下,如果不使用窗口,发送方就需要重传第二、三个数据包,但是有了窗口的概念后,发送方就省略了两次重传。因此使用窗口实际上可以理解为“空间换时间”。
某些确认包丢失时不用重发
流量控制
- 窗口大小
如果窗口过大,会导致接收方的缓存区数据溢出。这时候本该被接收的数据反而丢弃了,就会导致无意义的重传。因此,窗口大小是一个可以改变的值,它由接收端主机控制,附加在 TCP 首部的“窗口大小”字段中。
- 慢启动
在连接建立的初期,如果窗口比较大,发送方可能会突然发送大量数据,导致网络瘫痪。因此,在通信一开始时,TCP 会通过慢启动算法得出窗口的大小,对发送数据量进行控制。
流量控制是由发送方和接收方共同控制的。刚刚我们介绍了接收方会把自己能够承受的最大窗口长度写在 TCP 首部中,实际上在发送方这里,也存在流量控制,它叫拥塞窗口。TCP 协议中的窗口是指发送方窗口和接收方窗口的较小值。
慢启动过程如下:
通信开始时,发送方的拥塞窗口大小为 1。每收到一个 ACK 确认后,拥塞窗口翻倍。
由于指数级增长非常快,很快地,就会出现确认包超时。
此时设置一个“慢启动阈值”,它的值是当前拥塞窗口大小的一半。
同时将拥塞窗口大小设置为 1,重新进入慢启动过程。
由于现在“慢启动阈值”已经存在,当拥塞窗口大小达到阈值时,不再翻倍,而是线性增加。
随着窗口大小不断增加,可能收到三次重复确认应答,进入“快速重发”阶段。
这时候,TCP 将“慢启动阈值”设置为当前拥塞窗口大小的一半,再将拥塞窗口大小设置成阈值大小(也有说加 3)。
拥塞窗口又会线性增加,直至下一次出现三次重复确认应答或超时。
以上过程可以用下图概括:
窗口大小变化示意图
强烈建议读者对照上述八个步骤理解这幅图!