应用层:各种应用软件,包括Web应用
表示层:数据格式的标识,基本压缩加密功能
会话层:控制应用程序之间的会话能力;如不同软件数据分发给不同软件
传输层:端到端传输数据的基本功能,如TCP、UDP
网络层:定义IP编址,定义路由基本功能,如不同设备的数据转发
数据链路层:定义数据的基本格式,如和传输,如何标识;如网卡MAC地址
物理层:底层数据传输,如网线,网卡标准。
网络七层模型是一个标准,而非实现
网络的四层模型是一个实现的应用模型
网络四层模型由七层模型简化合并而来。
计算机网络体系大致分为三种,OSI七层模型、TCP/IP四层模型和五层模型。一般面试的时候考察比较多的是五层模型
TCP协议在传输层,IP协议在网络层
数据包校验:目的是检测数据在传输过程中的任何变化,若校验出包有错,则丢弃报文段并且不给出响应,这时 TCP 发送数据端超时后会重发数据;
对失序数据包重排序:既然 TCP 报文段作为 IP 数据报来传输,而 IP 数据报的到达可能会失序,因此 TCP 报文段的到达也可能会失序。TCP 将对失序数据进行重新排序,然后才交给应用层;
丢弃重复数据:对于重复数据,能够丢弃重复数据;
应答机制:当 TCP 收到发自 TCP 连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒;
超时重发:当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段;
流量控制:TCP 连接的每一方都有固定大小的缓冲空间。TCP 的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制。TCP 使用的流量控制协议是可变大小的滑动窗口协议。
拥塞控制和流量控制不同,前者是一个全局性的过程,而后者指点对点通信量的控制。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫拥塞。
拥塞控制就是为了防止过多的数据注入到网络中,这样就可以使网络中的路由器或链路不致于过载。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机,所有的路由器,以及与降低网络传输性能有关的所有因素。
相反,流量控制往往是点对点通信量的控制,是个端到端的问题。流量控制所要做到的就是抑制发送端发送数据的速率,以便使接收端来得及接收。
为了进行拥塞控制,TCP 发送方要维持一个拥塞窗口(cwnd) 的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。
TCP 的拥塞控制采用了四种算法,即:慢开始、拥塞避免、快重传和快恢复。在网络层也可以使路由器采用适当的分组丢弃策略(如:主动队列管理 AQM),以减少网络拥塞的发生。
慢开始:
慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd 初始值为 1,每经过一个传播轮次,cwnd 加倍。
拥塞避免:
拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢增大,即每经过一个往返时间 RTT 就把发送方的 cwnd 加 1。
快重传与快恢复:
在 TCP/IP 中,快速重传和快恢复(fast retransmit and recovery,FRR)是一种拥塞控制算法,它能快速恢复丢失的数据包。
没有 FRR,如果数据包丢失了,TCP 将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了 FRR,如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。
有了 FRR,就不会因为重传时要求的暂停被耽误。当有单独的数据包丢失时,快速重传和快恢复(FRR)能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时,它则不能很有效地工作。
表示层:数据格式的标识,基本压缩加密功能
应用层、传输层、网络层、数据链路层、物理层。
应用层:为应用程序提供交互服务。在互联网中的应用层协议很多,如域名系统DNS、HTTP协议、SMTP协议等。
传输层:负责向两台主机进程之间的通信提供数据传输服务。传输层的协议主要有传输控制协议TCP和用户数据协议UDP。
网络层:选择合适的路由和交换结点,确保数据及时传送。主要包括IP协议。
数据链路层:在两个相邻节点之间传送数据时,数据链路层将网络层交下来的 IP 数据报组装成帧,在两个相邻节点间的链路上传送帧。
物理层:实现相邻节点间比特流的透明传输,尽可能屏蔽传输介质和物理设备的差异。
应用层:支持各种网络应用 FTP SMTP HTTP
传输层: 进程-进程的数据传输 TCP UDP
网络层:源主机到目的主句的数据分组路由与转发 IP ICMP OSPF
数据链路层:把网络层传下来的数据报组装成帧 Ethernet PPP
物理层 : 比特传输
(1)TCP是面向连接的运输层协议;所谓面向连接就是双方传输数据之前,必须先建立一条通道,例如三次握手就是建议通道的一个过程,而四次挥手则是结束销毁通道的一个其中过程。
(2)每一条TCP连接只能有两个端点(即两个套接字),只能是点对点的;
(3)TCP提供可靠的传输服务。传送的数据无差错、不丢失、不重复、按序到达;
(4)TCP提供全双工通信。允许通信双方的应用进程在任何时候都可以发送数据,因为两端都设有发送缓存和接受缓存;
(5)面向字节流。虽然应用程序与TCP交互是一次一个大小不等的数据块,但TCP把这些数据看成一连串无结构的字节流,它不保证接收方收到的数据块和发送方发送的数据块具有对应大小关系,例如,发送方应用程序交给发送方的TCP10个数据块,但就受访的TCP可能只用了4个数据块久保收到的字节流交付给上层的应用程序,但字节流完全一样。
(1)UDP是无连接的传输层协议;
(2)UDP使用尽最大努力交付,不保证可靠交付;
(3)UDP是面向报文的,对应用层交下来的报文,不合并,不拆分,保留原报文的边界;
(4)UDP没有拥塞控制,因此即使网络出现拥塞也不会降低发送速率;
(5)UDP支持一对一 一对多 多对多的交互通信;
(6)UDP的首部开销小,只有8字节.
HTTP、HTTPS、传输文件的FTP、TELNET、发送和接收电子邮件的SMTP(简单邮件传输协议)协议基于可靠的TCP协议。
DNS、DHCP、TFTP、SNMP(简单网络管理协议)、RIP基于不可靠的UDP协议
TCP
(1)客户端程序和服务端程序需要多次交互才能实现应用程序的功能。比如接收电子邮件使用的POP3和发送电子邮件的SMTP,传输文件的FTP,在传输层使用的是TCP。
(2)应用程序传输的文件需要分段传输,比如浏览器访问网页,网页中图片和HTML文件需要分段后发送给浏览器,或QQ传文件,在传输层也是选用TCP
TCP应用场景: 效率要求相对低,但对准确性要求相对高的场景。因为传输中需要对数据确认、重发、排序等操作,相比之下效率没有UDP高。例如:文件传输(准确高要求高、但是速度可以相对慢)、接受邮件、远程登录。
UDP
(1)客户端程序和服务端程序通信,应用程序发送的数据包不需要分段。比如域名解析,DNS协议就是用传输层的UDP,客户端向DNS服务器发送一个报文解析某个网站的域名,DNS服务器将解析的结果使用一个报文返回给客户端。
(2)实时通信,比如QQ或微信语音聊天,或视频聊天。这类应用,发送端和接收端需要实时交互,也就是不允许较长延迟,即便有几句话因为网络堵塞没听清,也不允许使用TCP等待丢失的报文,等待的时间太长了,就不能愉快的聊天了。
(3)多播或广播通信。比如学校多媒体机房,老师的电脑屏幕需要教室的学生电脑接收屏幕,在老师的电脑安装多媒体教室服务端软件,学生电脑安装多媒体教室客户端软件,老师电脑使用多播地址或广播地址发送报文,学生电脑都能收到。这类应用在传输层使用UDP
UDP应用场景: 效率要求相对高,对准确性要求相对低的场景。例如:QQ聊天、在线视频、网络语音电话(即时通讯,速度要求高## TCP 协议是如何保证可靠传输的?
可靠传输有如下两个特点:
a. 传输信道无差错,保证传输数据正确
b. 不管发送方以多快的速度发送数据,接收方总是来得及处理接收到的数据
(1)首先,利用三次握手来建立TCP连接,四次挥手来释放TCP连接,从而保证建立的传输信道是可靠的
(2)其次,TCP采用了连续的AQR协议(回退N,Go-back-N;超时自动重传)来保证数据传输的正确性,采用滑动窗口协议来保证接收方能够即使处理所接收到的数据,并进行流量控制。
(3)最后,TCP使用慢开始、拥塞避免、快重传和快恢复来进行拥塞控制,避免网络拥塞。
停止等待 就是每发送完一个分组就停止发送,等待对方确认。在收到确认后再发送下一个分组。
在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认主要包括以下几种情况:
Automatic Repeat-reQuest 自动重传请求
自动重传请求AQR协议
其实是停止协议的一部分,不过是针对异常情况:
超时重传是指只要超过一段时间仍然没有收到确认,就重传前面发送过的分组(认为刚才发送过的分组丢失了),因此每一次发送完一个分组需要设置一个超时计时器,其重传时间比数据在分组传输的平均往返时间更长一些。
这种自动重传方式常称为自动重传请求AQR
连续AQR协议
连续AQR协议可以提高信道利用率。发送方维持一个发送窗口,凡是位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采取累计确认,对按序到达的最后一个分组发送确认,表明这个分组为止的所有分组都已经确认正确收到了,常用于滑动窗口一起用的
假设发送端为客户端,接收端为服务端。开始时客户端和服务端的状态都是CLOSED
。
第一次握手前客户端的状态为CLOSE,第一次握手后客户端的状态为SYN-SENT。此时服务端的状态为LISTEN。
第二次握手前服务端的状态为LISTEN,第二次握手后服务端的状态为SYN-RCVD,此时客户端的状态为SYN-SENT。(其中SYN=1表示要和客户端建立一个连接,ACK=1表示确认序号有效)
第三次握手前客户端的状态为SYN-SENT,第三次握手后客户端和服务端的状态都为ESTABLISHED。此时连接建立完成。
(TCP三次握手怎么回事?答: 流程+两个原因)
CLOSED:初始状态,表示TCP连接是“关闭着的”或者是“未打开的”
LISTEN:表示服务器端的某个SOCKET处于监听状态,可以接收客户端的连接
SYN_RCVD:表示服务器已经接收到了来自客户端请求连接的SYN报文。这个状态是在服务器端的,但是他是一个中间状态,很短暂。
平常用netstat或ss的时候,不太容易看到这种状态,但是遇到SYN flood之类的SYN攻击时,会出现大量这种状态,即收不到三次握手最后一个客户端发来的ACK,所以一直是这个状态,不会转换道ESTABLISHED
以上是三次握手的5种状态。
以上就是四次挥手的6种状态。
第三次握手主要为了防止已失效的连接请求报文段突然又传输到了服务端,导致产生问题。
A的应用进程先向其TCP发出连接释放报文段(FIN=1,seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN-WAIT-1(终止等待1)状态,等待B的确认。
B收到连接释放报文段后即发出确认报文段(ACK=1,ack=u+1,seq=v),B进入CLOSE-WAIT(关闭等待)状态,此时的TCP处于半关闭状态,A到B的连接释放。
A收到B的确认后,进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。
B发送完数据,就会发出连接释放报文段(FIN=1,ACK=1,seq=w,ack=u+1),B进入LAST-ACK(最后确认)状态,等待A的确认。
A收到B的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),A进入TIME-WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL(最大报文段生存时间)后,A才进入CLOSED状态。B收到A发出的确认报文段后关闭连接,若没收到A发出的确认报文段,B就会重传连接释放报文段。
因为当Server端收到Client端的SYN
连接请求报文后,可以直接发送SYN+ACK
报文。**但是在关闭连接时,当Server端收到Client端发出的连接释放报文时,很可能并不会立即关闭SOCKET,**所以Server端先回复一个ACK报文,告诉Client端我收到你的连接释放报文了。只有等到Server端所有的报文都发送完了,这时Server端才能发送连接释放报文,之后两边才会真正的断开连接。故需要四次挥手。
HTTP协议
HTTP请求由请求行、请求头部、空行和请求体四个部分组成。
请求行:包括请求方法,访问的资源URL,使用的HTTP版本。GET和POST是最常见的HTTP方法,除此以外还包括DELETE、HEAD、OPTIONS、PUT、TRACE。
请求头:格式为“属性名:属性值”,服务端根据请求头获取客户端的信息,主要有cookie、host、connection、accept-language、accept-encoding、user-agent。
请求体:用户的请求数据如用户名,密码等。
请求报文示例:
POST /xxx HTTP/1.1 请求行
Accept:image/gif.image/jpeg, 请求头部
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate
username=dabin 请求体
HTTP响应也由四个部分组成,分别是:状态行、响应头、空行和响应体。
状态行:协议版本,状态码及状态描述。
响应头:响应头字段主要有connection、content-type、content-encoding、content-length、set-cookie、Last-Modified,、Cache-Control、Expires
。
响应体:服务器返回给客户端的内容。
响应报文示例:
HTTP/1.1 200 OK
Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2003 13:23:42 GMT
Content-Length:112
<html>
<body>响应体</body>
</html>
会细问:1xx:表示请求已接受,继续处理;2xx:成功;3xx重定向;4xx客户端错误;5xx服务器端错误
301,302 都是 HTTP 状态的编码,都代表着某个 URL 发生了转移,不同之处在于:
301 redirect: 301 代表永久性转移(Permanently Moved)。
302 redirect: 302 代表暂时性转移(Temporarily Moved )。
字面上的区别就是 301 是永久重定向,而 302 是临时重定向。 当然,他们之间也是有共同点的,就是用户都可以看到 url 替换为了一个新的,然后发出请求。
301 比较常用的场景是使用域名跳转。比如,我们访问 会跳转到 ,发送请求之后,就会返回 301 状态码,然后返回一个 location,提示新的地址,浏览器就会拿着这个新的地址去访问。
注意:301 请求是可以缓存的, 即通过看 status code,可以发现后面写着 from cache。或者你把你的网页的名称从 php 修改为了 html,这个过程中,也会发生永久重定向。
302 用来做临时跳转,比如未登陆的用户访问用户中心重定向到登录页面。访问 404 页面会重新定向到首页。
总结:
302 重定向只是暂时的重定向,搜索引擎会抓取新的内容而保留旧的地址,因为服务器返回 302,所以,搜索搜索引擎认为新的网址是暂时的。 而 301 重定向是永久的重定向,搜索引擎在抓取新的内容的同时也将旧的网址替换为了重定向之后的网址。
使用场景、安全性、幂等性、可缓存、XMLHttpRequest
GET方法一般用于获取某种资源信息、 POST 用于传输实体主体(而POST方法一般用于将数据上传给服务器)
GET方法和POST方法都可以带参:GET方法是通过url传参的;POST方法是通过正文传参的
POST方法通过正文传参能传递更多的参数,而url的长度是有限,所以GET方式传参有限
POST方法传参更加私密,因为GET方法会将参数回显到url当中,POST方法在正文中不会被别人轻易看到。但是实际两种方法都不安全,POST方法传参可以被截取,要做到安全只能通过加密来完成
安全的 HTTP 方法不会改变服务器状态,也就是说它只是可读的。
GET 方法是安全的,而 POST 却不是,因为 POST 的目的是传送实体主体内容,这个内容可能是用户上传的表单数据,上传成功之后,服务器可能把这个数据存储到数据库中,因此状态也就发生了改变。
安全的方法除了 GET 之外还有:HEAD、OPTIONS。
不安全的方法除了 POST 之外还有 PUT、DELETE
get比post安全? -->get对于服务器是安全的–> get是幂等的,post是非幂等的
**HTTP1.0默认使用的是短连接。**浏览器和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。
**HTTP/1.1起,默认使用长连接。**要使用长连接,客户端和服务器的HTTP首部的Connection都要设置为keep-alive,才能支持长连接。
HTTP长连接,指的是复用TCP连接。多个HTTP请求可以复用同一个TCP连接,这就节省了TCP连接建立和断开的消耗。
长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。每个 TCP 连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多, 所以每个操作完后都不断开,下次处理时直接发送数据包就 OK 了,不用建立 TCP 连接。例如: 数据库的连接用长连接, 如果用短连接频繁的通信会造成 socket 错误,而且频繁的 socket创建也是对资源的浪费。
而像 WEB 网站的 http 服务一般都用短链接,因为长连接对于服务端来说会耗费一定的 资源,而像 WEB 网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源, 如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连接。
长连接 HTTP 1.0 需要使用 keep-alive 参数来告知服务器端要建立一个长连接,而 HTTP1.1 默认支持长连接。 HTTP 是基于 TCP/IP 协议的,创建一个 TCP 连接是需要经过三次握手的,有一定的开销,如果每次通讯都要重新建立连接的话,对性能有影响。因此最好能维持一个长连接,可以用个长连接来发多个请求。
节约带宽 HTTP 1.1 支持只发送 header 信息(不带任何 body 信息),如果服务器认为客户端有权限请求服务器,则返回 100,否则返回 401。客户端如果接受到 100,才开始把请求 body 发送到服务器。 这样当服务器返回 401 的时候,客户端就可以不用发送请求 body 了,节约了带宽。 另外 HTTP 还支持传送内容的一部分。这样当客户端已经有一部分的资源后,只需要跟服务器请求另外的部分资源即可。这是支持文件断点续传的基础。
HOST 域 现在可以 web server 例如 tomat,设置虚拟站点是非常常见的,也即是说,web server 上的多个虚拟站点可以共享同一个 ip 和端口。 HTTP1.0 是没有 host 域的,HTTP1.1 才支持这个参数。
HTTP2.0相比HTTP1.1支持的特性:
新的二进制格式:HTTP1.1 基于文本格式传输数据;HTTP2.0采用二进制格式传输数据,解析更高效。
多路复用:在一个连接里,允许同时发送多个请求或响应,并且这些请求或响应能够并行的传输而不被阻塞,避免 HTTP1.1 出现的”队头堵塞”问题。
头部压缩,HTTP1.1的header带有大量信息,而且每次都要重复发送;HTTP2.0 把header从数据中分离,并封装成头帧和数据帧,使用特定算法压缩头帧,有效减少头信息大小。并且HTTP2.0在客户端和服务器端记录了之前发送的键值对,对于相同的数据,不会重复发送。比如请求a发送了所有的头信息字段,请求b则只需要发送差异数据,这样可以减少冗余数据,降低开销。
服务端推送:HTTP2.0允许服务器向客户端推送资源,无需客户端发送请求到服务器获取。
HTTP 报文使用明文方式发送,可能被第三方窃听。
HTTP 报文可能被第三方截取后修改通信内容,接收方没有办法发现报文内容的修改。
HTTP 还存在认证的问题,第三方可以冒充他人参与通信。
HTTPS HTTPS不是新协议 而是先让HTTP与SSL(Secure Scokets Layer) 通信,再由SSL与TCP通信 (HTTPS使用了隧道进行通信) 通过***L, HTTPS具有加密(防窃听) 认证(防伪装) 以及完整性保护(防篡改)
开销:HTTPS 协议需要到 CA 申请证书,一般免费证书很少,需要交费;
资源消耗:HTTP 是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的 ssl 加密传输协议,需要消耗更多的 CPU 和内存资源;
端口不同:HTTP 和 HTTPS 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443;
安全性:HTTP 的连接很简单,是无状态的;HTTPS 协议是由 TLS+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全
对称加密中,双方使用公钥进行解密。虽然数字签名可以保证数据不被替换,但是数据是由公钥加密的,如果公钥也被替换,则仍然可以伪造数据,因为用户不知道对方提供的公钥其实是假的。所以为了保证发送方的公钥是真的,CA 证书机构会负责颁发一个证书,里面的公钥保证是真的,用户请求服务器时,服务器将证书发给用户,这个证书是经由系统内置证书的备案的。
服务端可以向证书颁发机构CA申请证书,以避免中间人攻击(防止证书被篡改)。证书包含三部分内容:证书内容、证书签名算法和签名,签名是为了验证身份。
服务端把证书传输给浏览器,浏览器从证书里取公钥。证书可以证明该公钥对应本网站。
数字签名的制作过程:2
CA使用证书签名算法对证书内容进行hash运算。
对hash后的值用CA的私钥加密,得到数字签名。
浏览器验证过程:
为了避免数据在传输过程中被替换,比如黑客修改了你的报文内容,但是你并不知道,所以我们让发送端做一个数字签名,把数据的摘要消息进行一个加密,比如 MD5,得到一个签名,和数据一起发送。然后接收端把数据摘要进行 MD5 加密,如果和签名一样,则说明数据确实是真的
首先是TCP三次握手,然后客户端发起一个HTTPS连接建立请求,客户端先发一个Client Hello
的包,然后服务端响应Server Hello
,接着再给客户端发送它的证书,然后双方经过密钥交换,最后使用交换的密钥加解密数据。
协商加密算法 。在Client Hello
里面客户端会告知服务端自己当前的一些信息,包括客户端要使用的TLS版本,支持的加密算法,要访问的域名,给服务端生成的一个随机数(Nonce)等。需要提前告知服务器想要访问的域名以便服务器发送相应的域名的证书过来。
服务端响应Server Hello
,告诉客户端服务端选中的加密算法。
接着服务端给客户端发来了2个证书。第二个证书是第一个证书的签发机构(CA)的证书。
HTTPS 指的是超文本传输安全协议,HTTPS 是基于 HTTP 协议的,不过它会使用 TLS/SSL 来对数据加密。
使用 TLS/SSL 协议,所有的信息都是加密的,第三方没有办法窃听。
并且它提供了一种校验机制,信息一旦被篡改,通信的双方会立刻发现。它还配备了身份证书,防止身份被冒充的情况出现。 https就是安全版本的http,譬如一些支付等操作基本都是基于https的,因为http请求的安全系数太低了。 简单来看,https与http的区别就是: 在请求前,会建立ssl链接,确保接下来的通信都是加密的,无法被轻易截取分析
客户端在使用 HTTPS 方式与 Web 服务器通信时有以下几个步骤: 1. 客户使用 https url 访问服务器,则要求 web 服务器建立 SSL 链接。 2. web 服务器接收到客户端的请求之后,会将网站的证书(证书中包含了公钥),返回或者说传输给客户端。 3. 客户端和 web 服务器端开始协商 SSL 链接的安全等级,也就是加密等级。 4. 客户端浏览器通过双方协商一致的安全等级,建立会话密钥,然后通过网站的公钥来加密会话密钥,并传送给网站。 5. web 服务器通过自己的私钥解密出会话密钥。 6. web 服务器通过会话密钥加密与客户端之间的通信。
第一步,客户端向服务器发起请求,请求中包含使用的协议版本号、生成的一个随机数、以及客户端支持的加密方法。 2. 第二步,服务器端接收到请求后,确认双方使用的加密方法、并给出服务器的证书、以及一个服务器生成的随机数。 3. 第三步,客户端确认服务器证书有效后,生成一个新的随机数,并使用数字证书中的公钥,加密这个随机数,然后发给服务器。并且还会提供一个前面所有内容的 hash 的值,用来供服务器检验。 4. 第四步,服务器使用自己的私钥,来解密客户端发送过来的随机数。并提供前面所有内容的 hash 值来供客户端检验。 5. 第五步,客户端和服务器端根据约定的加密方法使用前面的三个随机数,生成对话秘钥,以后的对话过程都使用这个秘钥来加密信息。
使用非对称密钥加密,传输对称加密所需要的Secret Key(Session Key),保证安全性 获取SecretKey后,使用对称加密方式进行通信,从而保证效率 ## 什么是数字签名? 为了避免数据在传输过程中被替换,比如黑客修改了你的报文内容,但是你并不知道,所以我们让发送端做一个数字签名,
把数据的摘要消息进行一个加密,比如 MD5,得到一个签名,和数据一起发送。
然后接收端把数据摘要进行 MD5 加密,如果和签名一样,则说明数据确实是真的。 ## 什么是数字证书? 对称加密中,双方使用公钥进行解密。虽然数字签名可以保证数据不被替换,但是数据是由公钥加密的,如果公钥也被替换,则仍然可以伪造数据,
因为用户不知道对方提供的公钥其实是假的。
所以为了保证发送方的公钥是真的,CA 证书机构会负责颁发一个证书,
里面的公钥保证是真的,用户请求服务器时,服务器将证书发给用户,这个证书是经由系统内置证书的备案的。
为了提高 DNS 查询效率,并减轻服务器的负荷和减少因特网上的 DNS 查询报文数量,在域名服务器中广泛使用了高速缓存,用来存放最近查询过的域名以及从何处获得域名映射信息的记录。
由于名字到地址的绑定并不经常改变,为保持高速缓存中的内容正确,域名服务器应为每项内容设置计时器并处理超过合理时间的项(例如:每个项目两天)。当域名服务器已从缓存中删去某项信息后又被请求查询该项信息,就必须重新到授权管理该项的域名服务器绑定信息。当权限服务器回答一个查询请求时,在响应中都指明绑定有效存在的时间值。增加此时间值可减少网络开销,而减少此时间值可提高域名解析的正确性。
不仅在本地域名服务器中需要高速缓存,在主机中也需要。许多主机在启动时从本地服务器下载名字和地址的全部数据库,维护存放自己最近使用的域名的高速缓存,并且只在从缓存中找不到名字时才使用域名服务器。维护本地域名服务器数据库的主机应当定期地检查域名服务器以获取新的映射信息,而且主机必须从缓存中删除无效的项。由于域名改动并不频繁,大多数网点不需花精力就能维护数据库的一致性。
在 HTTP/1.0 中默认使用短连接。也就是说,客户端和服务器每进行一次 HTTP 操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个 HTML 或其他类型的 Web 页中包含有其他的 Web 资源(如:JavaScript 文件、图像文件、CSS 文件等),每遇到这样一个 Web 资源,浏览器就会重新建立一个 HTTP 会话。
而从 HTTP/1.1 起,默认使用长连接,用以保持连接特性。使用长连接的 HTTP 协议,会在响应头加入这行代码:
Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输 HTTP 数据的 TCP 连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。
Keep-Alive 不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如:Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。
1、 客户端发送自己支持的加密规则给服务器,代表告诉服务器要进行连接了;
2、 服务器从中选出一套加密算法和 hash 算法以及自己的身份信息(地址等)以证书的形式发送给浏览器,证书中包含服务器信息,加密公钥,证书的办法机构;
3、客户端收到网站的证书之后要做下面的事情:
验证证书的合法性;
如果验证通过证书,浏览器会生成一串随机数,并用证书中的公钥进行加密;
用约定好的 hash 算法计算握手消息,然后用生成的密钥进行加密,然后一起发送给服务器。
4、服务器接收到客户端传送来的信息,要做下面的事情:
4.1 用私钥解析出密码,用密码解析握手消息,验证 hash 值是否和浏览器发来的一致;
4.2 使用密钥加密消息;
5、如果计算法 hash 值一致,握手成功。
优点:
使用 HTTPS 协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;
HTTPS 协议是由 SSL + HTTP 协议构建的可进行加密传输、身份认证的网络协议,要比 HTTP 协议安全,可防止数据在传输过程中被窃取、改变,确保数据的完整性;
HTTPS 是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。
缺点:
HTTPS 协议握手阶段比较费时,会使页面的加载时间延长近 50%,增加 10% 到 20% 的耗电;
HTTPS 连接缓存不如 HTTP 高效,会增加数据开销和功耗,甚至已有的安全措施也会因此而受到影响;
SSL 证书需要钱,功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用;
SSL 证书通常需要绑定 IP,不能在同一 IP 上绑定多个域名,IPv4 资源不可能支撑这个消耗;
HTTPS 协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。最关键的,SSL 证书的信用链体系并不安全,特别是在某些国家可以控制 CA 根证书的情况下,中间人攻击一样可行。
由于HTTP协议是无状态的协议,需要用某种机制来识具体的用户身份,用来跟踪用户的整个会话。常用的会话跟踪技术是cookie与session。
cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息。说得更具体一些:当用户使用浏览器访问一个支持cookie的网站的时候,用户会提供包括用户名在内的个人信息并且提交至服务器;接着,服务器在向客户端回传相应的超文本的同时也会发回这些个人信息,当然这些信息并不是存放在HTTP响应体中的,而是存放于HTTP响应头;当客户端浏览器接收到来自服务器的响应之后,浏览器会将这些信息存放在一个统一的位置。 自此,客户端再向服务器发送请求的时候,都会把相应的cookie存放在HTTP请求头再次发回至服务器。服务器在接收到来自客户端浏览器的请求之后,就能够通过分析存放于请求头的cookie得到客户端特有的信息,从而动态生成与该客户端相对应的内容。网站的登录界面中“请记住我”这样的选项,就是通过cookie实现的。
cookie工作流程:
session原理:首先浏览器请求服务器访问web站点时,服务器首先会检查这个客户端请求是否已经包含了一个session标识、称为SESSIONID,如果已经包含了一个sessionid则说明以前已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用,如果客户端请求不包含session id,则服务器为此客户端创建一个session,并且生成一个与此session相关联的独一无二的sessionid存放到cookie中,这个sessionid将在本次响应中返回到客户端保存,这样在交互的过程中,浏览器端每次请求时,都会带着这个sessionid,服务器根据这个sessionid就可以找得到对应的session。以此来达到共享数据的目的。 这里需要注意的是,session不会随着浏览器的关闭而死亡,而是等待超时时间。
作用范围不同,Cookie 保存在客户端,Session 保存在服务器端。
有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。
隐私策略不同,Cookie 存储在客户端,容易被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。
存储大小不同, 单个 Cookie 保存的数据不能超过 4K;对于 Session 来说存储没有上限,但出于对服务器的性能考虑,Session 内不要存放过多的数据,并且需要设置 Session 删除机制。
(1、由于HTTP协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是Session.典型的场景比如购物车。
当你点击下单按钮时,由于HTTP协议无状态,所以并不知道是哪个用户操作的,所以服务端要为特定的用户创建了特定的Session,用用于标识这个用户,并且跟踪用户,这样才知道购物车里面有几本书。
这个Session是保存在服务端的,有一个唯一标识。在服务端保存Session的方法很多,内存、数据库、文件都有。集群的时候也要考虑Session的转移,在大型的网站,一般会有专门的Session服务器集群,用来保存用户会话,这个时候 Session 信息都是放在内存的,使用一些缓存服务比如Memcached之类的来放 Session。
2、思考一下服务端如何识别特定的客户?这个时候Cookie就登场了。每次HTTP请求的时候,客户端都会发送相应的Cookie信息到服务端。实际上大多数的应用都是用 Cookie 来实现Session跟踪的,第一次创建Session的时候,服务端会在HTTP协议中告诉客户端,需要在 Cookie 里面记录一个Session ID,以后每次请求把这个会话ID发送到服务器,我就知道你是谁了。
有人问,如果客户端的浏览器禁用了 Cookie 怎么办?一般这种情况下,会使用一种叫做URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。
3、Cookie其实还可以用在一些方便用户的场景下,设想你某次登陆过一个网站,下次登录的时候不想再次输入账号了,怎么办?这个信息可以写到Cookie里面,访问网站的时候,网站页面的脚本可以读取这个信息,就自动帮你把用户名给填了,能够方便一下用户。这也是Cookie名称的由来,给用户的一点甜头。
所以,总结一下:
Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中。
Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。)
对称加密:通信双方使用相同的密钥进行加密。
特点是加密速度快,但是缺点是密钥泄露会导致密文数据被破解。常见的对称加密有AES
和DES
算法。
非对称加密:它需要生成两个密钥,公钥和私钥。公钥是公开的,任何人都可以获得,而私钥是私人保管的。公钥负责加密,私钥负责解密;或者私钥负责加密,公钥负责解密。这种加密算法安全性更高,但是计算量相比对称加密大很多,加密和解密都很慢。常见的非对称算法有RSA
和DSA
。
存在问题:原有的超时重传和确认应答,影响了数据的传输效率,因为每次客户端要收到ACK之后再发下一份数据,就多了一些等待时间
解决方案:批量发送数据,批量接受ACK
滑动窗口就是为了提高TCP的传输效率,等待ACK的时间缩短了
接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被打满, 这个时候如果发送端继续发送, 就会造成丢包, 继而引起丢包重传等等一系列连锁反应.
因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫做流量控制(Flow Control)
TCP 利用滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,保证接收方来得及接收。 TCP会话的双方都各自维护一个发送窗口和一个接收窗口。接收窗口大小取决于应用、系统、硬件的限制。发送窗口则取决于对端通告的接收窗口。接收方发送的确认报文中的window字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将接收方的确认报文window字段设置为 0,则发送方不能发送数据。
TCP头包含window字段,16bit位,它代表的是窗口的字节容量,最大为65535。这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。接收窗口的大小是约等于发送窗口的大小。
防止过多的数据注入到网络中。 几种拥塞控制方法:慢开始( slow-start )、拥塞避免( congestion avoidance )、快重传( fast retransmit )和快恢复( fast recovery )。
把拥塞窗口 cwnd 设置为一个最大报文段MSS的数值。而在每收到一个对新的报文段的确认后,把拥塞窗口增加至多一个MSS的数值。每经过一个传输轮次,拥塞窗口 cwnd 就加倍。 为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量。
当 cwnd < ssthresh 时,使用慢开始算法。
当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞控制避免算法。
让拥塞窗口cwnd缓慢地增大,每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口cwnd按线性规律缓慢增长。
无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送 方窗口值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生 拥塞的路由器有足够时间把队列中积压的分组处理完毕。
有时个别报文段会在网络中丢失,但实际上网络并未发生拥塞。如果发送方迟迟收不到确认,就会产生超时,就会误认为网络发生了拥塞。这就导致发送方错误地启动慢开始,把拥塞窗口cwnd又设置为1,因而降低了传输效率。
快重传算法可以避免这个问题。快重传算法首先要求接收方每收到一个失序的报文段后就立即发出重复确认,使发送方及早知道有报文段没有到达对方。
发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待重传计时器到期。由于发送方尽早重传未被确认的报文段,因此采用快重传后可以使整个网络吞吐量提高约20%。
当发送方连续收到三个重复确认,就会把慢开始门限ssthresh减半,接着把cwnd值设置为慢开始门限ssthresh减半后的数值,然后开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大。
在采用快恢复算法时,慢开始算法只是在TCP连接建立时和网络出现超时时才使用。 采用这样的拥塞控制方法使得TCP的性能有明显的改进。
ARP解决了同一个局域网上的主机和路由器IP和MAC地址的解析。
同步IO,是一种用户空间和内核空间的IO发起方式。同步是指用户空间的线程是主动发起IO请求的一方,内核空间是被动接受方。异步IO则反过来,是指系统内核是主动发起IO请求的一方,用户空间的线程是被动接受方。
异步IO,指的是用户空间与内核空间的调用方式反过来。用户空间的线程变成被动接受者,而内核空间成了主动调用者。这有点类似于Java中比较典型的回调模式,用户空间的线程向内核空间注册了各种IO事件的回调函数,由内核去主动调用
粘包是指为了防止数据量过小导致大量传输,全将多个 TCP 段合并成一个发送。就是将若干个包数据粘成一个包,
从接收缓冲区看,后一包数据的头紧接送前一包数据的尾。因为 TCP 层传输是流式传输,流,最大的问题是没有边界,没有边界就会造成数据粘在一起。 拆包就是将任务拆分处理了,降低出错率。
接收方不及时接收缓冲区的包,造成多个包接收
因为 TCP 默认使用 Nagle 算法,这个算法本身也可能会导致粘包问题
由于 TCP 的复用造成粘包。由于 TCP 连接的复用性,建立一条连接可以供一台主机上的多个进程使用,那么多种不同结构的数据到 TCP 的流式传输里,边界分割肯定会出现奇葩的问题
数据包过大造成的粘包问题,比如应用进程缓冲区的一条消息内容大小超过了发送缓存区的大小,就可能产生粘包,因为消息已经被分割了,前一部分已经被接收了,但另一部分可能刚放入缓存冲区准备发送,这样就会导致后一部分粘包
流量控制,拥塞控制也可能导致粘包
Nagle 算法,主要做两件事: 一是只有上一个分组得到确认,才会发送下一个分组; 二是收集多个小分组,数据包大小达到最大段大小(MSS),在一个确认到来时一起发送。 多个分组拼成一个数据段发出去,如果没有处理好边界问题,在解包的时候就会发生粘包
如果是 Nagle 算法导致的,结合应用场景适当关闭算法就可以了
如果不是
尾部标记序列。通过特殊标识符表示数据包的边界,比如\n\r\t 或一些隐藏字符
头部标记分步接收。在 TCP 报文的头部加上表示数据长度。使用带消息头的协议,消息头存储开始标识及消息长度信息,服务商获取消息头的时候解析出消息长度,然后向后读取该长度的内容
应用层发送数据时定长发送,服务端读取既定长度的内容作为一条完整消息,如果不够长,就在空位上补固定字符
因为 UDP 是面向消息的协议,UDP 段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据
UDP 具有保护消息边界,在每个 UDP 包中有消息头(消息来源地址,端口信息等),这样对于接收端来说容易进行分区处理。传输协议把数据当作一条独立的消息在网上传输,接收方只能接收独立的消息,如果消息内容过大,超过接收方一次所能接受的大小,就会丢失一部分数据,因为就算是丢失,它也不会分两次去接收.
如果客户端连续不断的向服务端发送数据包时,服务端接收的数据会出现两个数据包粘在一起的情况。
基于上面,在使用 TCP 传输数据时,才有粘包或者拆包现象发生的可能。一个数据包中包含了发送端发送的两个数据包的信息,这种现象即为粘包。
分包机制一般有两个通用的解决方法:
特殊字符控制;
在包头首都添加数据包的长度。
如果使用 netty 的话,就有专门的编码器和解码器解决拆包和粘包问题了。
tips:UDP 没有粘包问题,但是有丢包和乱序。不完整的包是不会有的,收到的都是完全正确的包。传送的数据单位协议是 UDP 报文或用户数据报,发送的时候既不合并,也不拆分。