分层体系
OSI 的七层协议体系结构的概念清楚,理论也较完整,但它既复杂又不实用。TCP/IP体系结构则不同,但它现在却得到了非常广泛的应用。
TCP/IP是一个四层的体系结构,它包含应用层、运输层、网际层和网络接口层。
应用层(application layer):应用层的任务是通过应用进程间的交互来完成特定网络应用。应用层协议定义的是应用进程间通信和交互的规则。在互联网中的应用层协议很多,如域名系统DNS,支持万维网应用的HTTP协议,支持电子邮件的SMTP协议等等。应用层交互的数据单元称为报文(message)。
运输层(transport layer):运输层的任务就是负责向两台主机中进程之间的通信提供通用的数据传输服务。应用进程利用该服务传送应用层报文。所谓“通用的”,是指并不针对某个特定网络应用,而是多种应用可以使用同一个运输层服务。由于一台主机可同时运行多个进程,因此运输层有复用和分用的功能。复用就是多个应用层进程可同时使用下面运输层的服务,分用和复用相反,是运输层把收到的信息分别交付上面应用层中的相应进程。运输层主要使用以下两种协议:
- 传输控制协议TCP(Transmission Control Protocol)—提供面向连接的、可靠的数据传输服务,其数据传输的单位是报文段(segment)。
- 用户数据报协议UDP(User Datagram Protocol)—提供无连接的、尽最大努力(best-effort)的数据传输服务(不保证数据传输的可靠性),其数据传输的单位是用户数据报。
网络层:网络层负责为分组交换网上的不同主机提供通信服务。在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组或包进行传送。在TCP/IP体系中,由于网络层使用IP协议,因此分组也叫做IP数据报,或简称为数据报。
- 网络层的另一个任务就是要选择合适的路由,使源主机运输层所传下来的分组,能够通过网络中的路由器找到目的主机。
- 不要将运输层的“用户数据报UDP”和网络层的“IP数据报”弄混。此外,无论在哪一层传送的数据单元,都可笼统地用“分组”来表示。
数据链路层(data link layer):两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议。在两个相邻结点之间传送数据时,数据链路层将网络层交下来的IP数据报组装成帧(framing),在两个相邻结点间的链路上传送帧(frame)。每一帧包括数据和必要的控制信息(如同步信息、地址信息、差错控制等)。
- 在接收数据时,控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。
- 控制信息还使接收端能够检测到所收到的帧中有无差错。
物理层(physical layer):考虑的是怎样在传输媒体上透明地传输数据比特流,而不是指具体的传输媒体。物理层的作用是尽可能屏蔽传输媒体和通信手段的差异,使数据链路层感觉不到这些差异。
请求方法
问题:POST 方法与 PUT 方法的区别?
方法名 | 作用 |
---|---|
GET |
向指定的资源发出“显示”请求。 |
PATCH |
用于将局部修改应用到资源。 |
POST |
向指定资源提交数据,请求服务器进行处理。 |
PUT |
向指定资源位置上传其最新内容。 |
DELETE |
请求服务器删除Request-URI所标识的资源。 |
HEAD |
与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。 |
TRACE |
回显服务器收到的请求,主要用于测试或诊断。 |
OPTIONS |
可使服务器传回该资源所支持的所有HTTP请求方法。 |
CONNECT |
通常用于SSL加密服务器的链接 |
GET 与 POST的区别
比较方面 | GET | POST |
---|---|---|
请求主体(Body) | 只有URL,无请求主体 | 有请求主体 |
响应主体 | 有 | 有 |
后退按钮/刷新 | 无副作用 | 数据会被重新提交 |
书签 | 可收藏为书签 | 不可收藏为书签 |
缓存 | 可被缓存 | 不能缓存 |
编码类型 | application/x-www-form-urlencoded |
application/x-www-form-urlencoded multipart/form-data text/plain |
历史 | 参数保留在浏览器历史中 | 参数不会保存在浏览器历史中 |
URL长度 | 有限制,但不同浏览器限制又不同。常说的2KB其实是指IE8,Chrome和Apache为8KB | 无限制(Post请求本身不限制长度,但是服务器是会限制的。) |
对数据类型的限制 | 只允许 ASCII 字符 | 没有限制、也允许二进制数据,Percent Encoding编码 |
安全性 | 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET | POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。 |
幂等性 | 支持 | 不支持 |
可见性 | 数据在 URL 中对所有人都是可见的 | 数据不会显示在 URL 中 |
状态码
所有HTTP响应的第一行都是状态行,依次是当前HTTP版本号,3位数字组成的状态代码,以及描述状态的短语,彼此由空格分隔。
状态代码的第一个数字代表当前响应的类型:
1xx消息——请求已被服务器接收,继续处理
2xx成功——请求已成功被服务器接收、理解、并接受
- 200: 正常返回信息
3xx重定向——需要后续操作才能完成这一请求
- 300 Multiple Choices
- 301 Moved Permanently: 资源已经被永久移动,通常会发送HTTP Location来重定向到正确的新位置。Google 认为这是将网站从HTTP迁移到HTTPS的最佳方法。
- 302 Found: 临时重定向。
当 301、302、303 响应状态码返回时,几乎所有的浏览器都会把 POST 改成 GET,并删除请求报文内的主体,之后请求会自动再次 发送。
301、302 标准是禁止将 POST 方法改变成 GET 方法的,但实际使 用时大家都会这么做。
- 304 Not Modified: 表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但未满足条件的情况。304 状态码返回时,不包含任何响应的主体部分。304 虽然被划分在 3XX 类别中,但是和重定向没有关系。
附带条件的请求是指采用 GET 方法的请求报文中包含 If-Match,If-Modified- Since,If-None-Match,If-Range,If-Unmodified-Since 中任一首部。
4xx请求错误——请求含有词法错误或者无法被执行
- 401 Unauthorized:请求未经授权,即用户没有权限执行这个请求。
- 403 Forbidden:服务器收到请求,但是拒绝提供服务
- 404 Not Found:请求资源不存在。最常见的就是URL错误
5xx服务器错误——服务器在处理某个正确请求时发生错误
- 500 Internal Server Error:服务器发生不可预期的错误
- 502 Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
- 503 Service Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常。
HTTP的缺点
- 通信使用明文(不加密),内容可能会被窃听。
- 不验证通信方的身份,因此有可能遭遇伪装。
- 无法证明报文的完整性,所以有可能已遭篡改。
HTTP各版本区别
HTTP1.0
- 短连接:每次发送请求都要重新建立 TCP 连接,即三次握手,数据发送完毕就要关闭连接。
- 无 host 头域,也就是 http 请求头里的 host。
- 不允许断点续传,而且不能只传输对象的一部分,要求传输整个对象。
HTTP1.1
- 引入了持久连接(persistent connectio),又称长连接。客户端和服务器发现对方一段时间没有活动,可以主动关闭连接。
- 引入了流水线机制(pipelining),也就是在同一个TCP连接里面,客户端可以同时发送多个请求。
- 采用”流模式”(stream)取代”缓存模式”(buffer),采用分块传输编码,产生一块数据,就发送一块。
- 客户端请求的头信息新增了 Host 字段,用来指定服务器的域名。
- 新增许多方法:PUT、PATCH、HEAD、 OPTIONS、DELETE。
- 将 Content-length 字段的作用进行扩充,声明本次回应(Response)的数据长度。
虽然 HTTP1.1 允许复用 TCP 连接,但是同一个 TCP 连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为”队头堵塞”(Head-of-line blocking)。
为了避免这个问题,只有两种方法:一是减少请求数,二是同时多开持久连接。
这产生了很多的网页优化技巧,比如合并脚本和样式表、将图片嵌入CSS代码、域名分片(domain sharding)等等。如果HTTP协议设计得更好一些,这些额外的工作是可以避免的。
HTTP1.x的缺点
- HTTP/1.0一次只允许在一个TCP连接上发起一个请求,HTTP/1.1 使用的流水线技术也只能部分处理请求并发,仍然会存在队列头阻塞问题,因此客户端在需要发起多次请求时,通常会采用建立多连接来减少延迟。
- 单向请求,只能由客户端发起。
- 请求报文与响应报文首部信息冗余量大。
- 数据未压缩,导致数据的传输量大。
HTTP2.0
主要基于SPDY协议(Google开发的基于TCP协议的应用层协议)
核心思想是尽量减少TCP连接数。
目标是优化HTTP协议的性能,通过压缩、多路复用和优先级等技术,缩短网页的加载时间并提高安全性。
在不改动HTTP语义、方法、状态码、URI及首部字段的情况下,大幅度提高了 Web 性能。
- 改用二进制传输,HTTP1.x 使用文本传输。
- 在应用层与传输层之间增加一个二进制分帧层,在二进制分帧层上,HTTP2.0 会将所有传输的信息分为更小的消息和帧,并采用二进制格式编码。
- 其中 HTTP1.x 的首部信息会被封装到 Headers帧,而Request Body则封装到 Data帧。
- 头部(Header)压缩:
- 使用 HPACK (头部压缩算法)压缩格式对传输的 header 进行编码,减小了 header 的体积。
- 在两端维护了索引表(Map),用于记录出现过的header,后面在传输过程中就可以传输已经记录过的 header 的键名,对端收到数据后就可以通过键名找到对应的值。
- 多路复用:使用多个流(stream),每个流分帧传输,使得一个 TCP 连接能够处理多个 HTTP 请求,避免 HTTP1.x版本的队头阻塞问题。
- 服务器端推送Push:服务端可以在客户端某个请求后,主动推送其他资源。
- 更安全:使用了 TLS 的 拓展ALPN 作为协议升级,除此之外,HTTP2.0 对 TLS 的安全性做了近一步加强,通过黑名单机制禁用了几百种不再安全的加密算法。
HTTP3.0
- 基于 Google 的 QUIC 协议,利用UDP实现可靠数据传输。
- 减少了 TCP 三次握手时间,减少了 TLS 握手时间。
- 解决了 HTTP 2.0 中前一个 stream 丢包导致后一个 stream 被阻塞的问题。
- 优化了重传策略,重传包和原包的编号不同,降低后续重传计算的消耗。
- 连接迁移,不再用 TCP 四元组确定一个连接,而是用一个 64 位随机数来确定这个连接。
- 更合适的流量控制。
HTTP 与 FTP
关于文件上传:
Feature | HTTP | FTP |
---|---|---|
侧重点 | 用来浏览网站、更多的是为终端用户提供文件传输,比如电影、图片、音乐。 | 用来访问和传输文件,FTP 文件传输常见于批量上传和维护网站。 |
客户端 | 通常是浏览器 | 命令行或特定的图形界面 |
头部 | 包含 meta-data,比如最后修改日期、编码方式、服务器名称等。 | 不支持 |
数据格式 | 只支持二进制格式文件 | 支持ASCII与二进制 |
流水线 | 支持流水线,这就意味着客户端可以在上一个请求处理完之前,发出下一个请求,其结果就是多次请求数据之前省掉了部分服务器客户端往返时延。 | 不支持 |
动态端口 | 在双向传输中使用动态端口 | 使用两个连接,第一个连接用来发送控制指令,当接收或者发送数据的时候,又打开第二个TCP连接。 |
持久连接(长连接) | 可以维护一个单个的连接并使用它进行任意数量的数据传输。 | 每次有数据的需要时都创建一个新的连接。 |
压缩算法 | 提供了在一些压缩算法中客户端和服务器共同协商选择的办法,比如 gzip。 | 不存在这种算法 |
对代理的支持 | 支持代理,这种功能是构建在协议里。 | 不支持 |
面向的对象 | 没有这个概念 | 面向文件,ftp 可以通过命令列出远程服务器的目录列表。 |
文件大小 | 比较适合上传小文件 | 比较适合上传大文件,不需要将文件全部载入内存中。 |
什么使 FTP 服务更快
- 发送数据中没有
meta-data
,仅传输原始的二进制文件。 - 没有过度的分块编码。
什么使HTTP服务更快?
- 重用已存在的持久连接,从而有更好的TCP表现。
- 流水线的支持使得从同一个服务器上请求多个文件更快。
- 自动的压缩机制使得传输的数据更少。
- 没有命令/应答机制最大限度的减少了往返时延。
HTTPS的工作流程
如何验证公钥证书
简易版的HTTPS工作流程
客户端发起HTTPS请求,连接到 Server 的 443 端口。
服务器检测并选择客户端能支持的加密方式
传送证书
服务器将自己的数字证书的部分信息返回给客户端,其中包括公钥,以及支持的SSL 版本等信息。
客户端解析证书
客户端首先会验证公钥是否有效,如果发现异常,则弹出警告。否则那么就生成一个随机值(Premaster Secret),然后用公钥对该随机值进行加密。
传送加密信息
传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。
服务端解密信息
服务端用与公钥配对的私钥解密后,得到客户端传过来的随机值。从客户端生成随机值到服务器解密获取随机值这个过程称为非对称加密。
传输加密后的信息
服务器用刚刚解密得到的随机值加密需要传输的内容,并将加密后的信息发送给客户端。
客户端解密信息
客户端用之前生成的随机值解密服务器传过来的信息,获取实际传输的内容。这个过程称为对称加密。
SSL 协商过程
继续借用《图解HTTP》中的图文。
HTTP连接需要交换3个包,而HTTPS连接需要交换 3(TCP) + 9 个包(SSL/TLS连接)。
这里说的加密过程是指 SSL 的加密,至于 TLS 的加密…
- 客户端发送 Client Hello 报文开始 SSL 通信。报文中包含客户端支持的 SSL 的指定版本、加密组件列表(所使用的加密算法及密钥长度等)。
- 服务器确定可进行 SSL 通信时,以 Server Hello 报文作为应答。报文中包含 SSL 版本以及加密组件(Cipher Suite)。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。
- 服务器继续发送 Certificate 报文。报文中包含公钥证书。
- 服务器继续发送 ServerHelloDone 报文。通知客户端第一阶段的 SSL 握手协商部分结束。
- 客户端发送 Client Key Exchange 报文作为回应。报文中包含通信加密中一种被称为
Pre-master secret
的随机密码串。这个报文已用第 3 步中的公钥进行加密。 - 客户端继续发送 Change Cipher Spec 报文。该报文会提示服务器,在此报文之后的通信都将会采用
Premaster secret
秘钥加密。 - 客户端发送 Finished 报文。该报文包含连接至今,全部报文的整体校验值。此次握手协商能否成功,取决于服务器能否正确解密该报文。
- 服务器同样发送 Change Cipher Spec 报文。
- 服务器继续发送 Finished 报文。
- 服务器与客户端交换完 Finished 报文之后,SSL 连接建立成功,通信将会受到 SSL 的保护。从此处开始进行应用层协议的通信,即发送 HTTP 请求。
- 应用层协议通信,即发送 HTTP 响应。
- 由客户端断开连接。发送 close_notify 报文,之后发送 TCP FIN 报文来关闭与 TCP 的通信。
下面是对整个流程的图解。图中说明了从仅使用服务器端的公开密钥证书(服务器证书)建立 HTTPS 通信的整个过程。
SSL 与 TLS
TLS 与 SSL 的差异
版本号:TLS 记录格式与 SSL 记录格式相同,但版本号的值不同,TLS1.0 使用的版本号为 SSLv3.1。
报文鉴别码:SSLv3.0 和 TLS 的 MAC 算法及 MAC 计算的范围不同。TLS 使用 HMAC 算法。SSLv3.0使用了相似的算法,两者差别在于 SSLv3.0 中,填充字节与密钥之间采用的是连接运算,而 HMAC 算法采用的是异或运算。
伪随机函数:TLS 使用了称为 PRF 的伪随机函数来将密钥扩展成数据块。
报警代码:TLS 在支持几乎所有的SSLv3.0报警代码的基础上,补充定义了很多报警代码,如解密失败(decryption_failed)、记录溢出(record_overflow)、未知CA(unknown_ca)、拒绝访问(access_denied)等。
密文族和客户证书:SSLv3.0 和 TLS 存在少量差别,TLS 不支持 Fortezza 密钥交换、加密算法和客户证书。
certificate_verify 和 finished 消息:SSLv3.0 和 TLS 在用 certificate_verify 和 finished 消息计算 MD5 和 SHA-1 散列码时,计算的输入有少许差别,但安全性相当。
加密计算:TLS 与 SSLv3.0 在计算主密值(master secret)时采用的方式不同。
填充:用户数据加密之前需要增加的填充字节。
- 在 SSL 中,填充后的数据长度要达到密文块长度的最小整数倍。
- 在 TLS 中,填充后的数据长度可以是密文块长度的任意整数倍(但填充的最大长度为255字节),这种方式可以防止基于对报文长度进行分析的攻击。
HTTP与HTTPS的区别
方面 | HTTP | HTTPS |
---|---|---|
开发目的 | 发布和接收 HTML 页面 浏览器和网站服务器之间传递信息 |
提供对网站服务器的身份认证 保护交换数据的隐私与完整性。 |
连接端口 | 80 | 443 |
安全协议 | 无 | SSL/TLS |
加密方式 | 无 | 对称加密、非对称加密、哈希算法、数字签名 |
安全性 | 明文传输、相对较低 | 加密传输、相对较高 |
建立连接 | TCP三次握手交换3个包 | TCP3个包+SSL9个包 |
响应速度 | 相对较快 | 相对较慢(比HTTP慢2到100倍) |
所需费用 | 免费 | 可能需要购买证书 |
Cookie 与 Session
由于 HTTP 协议是无状态的协议,每一个 HTTP 请求都是互相独立的,服务器分辨不出两次请求是否来自同一个浏览器或同一位用户。
所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是 Session。
Cookie 简介
- 浏览器第一次连接服务器时 Cookie 是不存在的
- 服务器响应客户端时,会在 Header 中设置 Set-Cookie,服务器收到 Cookie 后存在本地。每一个 Cookie 都是 name-value 对。
- 此后浏览器再连接服务器,都会包含上 Cookie,服务器可以用它来关联特定的请求。
Cookie里有什么?
- Name and data.
- 数据大小通常被浏览器所限定,一般小于 4KB。
- 一个服务器可以通过不同的 Name 定义多个 Cookie,但是浏览器限制了每一个服务器可以拥有的 Cookie 数量(50个左右)。
- 当前 Cookie 的 Domain(作用域)信息:Server、port(可选)、URL 前缀(可选)。Cookie 只会被包含在匹配的作用域的请求之中。
- 过期时间:浏览器可以删除老旧的 Cookies。
工作流程
由服务器发给客户端的特殊信息,以文本的形式存放在客户端
客户端再次请求的时候,会把
Cookie
回发服务器收到后,会解析
Cookie
生成与客户端相对应的内容
Session简介
- Cookie 是服务器用来实现 Session 的一种方式
- Cookie 中包含了 Session 的表示,通常被称为 SessionID。
- Session 的管理
- 可以储存在内存里
- 或者储存在磁盘中的文件中
- 或者存在数据库中
简单工作流程
- 保存在服务器上的信息
- 解析客户端请求并操作
SessionId
,按需保存状态信息。 - 实现方式
- 使用
Cookie
来实现 - 当客户端禁用
Cookie
时,可以使用URL
回写来实现
- 使用
Cookie
和 Session
的区别
对比角度 | Cookie | Session |
---|---|---|
存放位置 | 位于客户端的一段文本、包含用户信息,是 Session 的一种实现方式。 | 位于服务器的文件,包含用户信息。在 Tomcat 中使用 StandardSession 实现,使用到的数据结构是 ConcurrentHashMap。 |
生存时间 | 可以手动设定 | 当关闭浏览器时就消失 |
容量大小 | 一般最大为 4KB | 理论上可以存储随意多的信息,唯一的限制是一个脚本一次最大能占用的内存,默认是128MB |
依赖性 | Cookie 不依赖于 Session,Cookie 是 Session 的一种实现方式。 | Session 依赖于 Cookie,当 Cookie 禁用时,可以通过 URL 回写来实现。 |
安全性 | 相对较低 | 相对较高 |
参考
- 《计算机网络》第七版,谢希仁。
- 《图解HTTP》上野 宣、于均良 译。
- 掘金 - Cookie 和 Session 关系和区别
- 简书 - 看完就彻底懂了session和cookie
- Stanford University - CS 142: Web Applications (Fall 2010)