网络模型
OSI七层模型(从上到下)
- 应用层
- 允许访问OSI的环境
- FTP HTTP DNS
- 表示层
- 对数据进行翻译、加密和压缩
- JPEG ASII
- 会话层
- 建立、管理和终止会话
- RPC NFS
- 传输层
- 提供端到端的报文传递和错误会恢复
- TCP UDP
- 网络层
- 负责数据包从源到宿的传递
- IP ARP
- 数据链路层
- 将bit组装成帧和点到点传递
- MAC PPP VLAN
- 物理层
- 媒介传输
TCP/IP四层模型(从上到下)
- 应用层
- FTP HTTP DNS
- 传输层
- TCP UDP
- 网络层
- IP ARP
- 网络接口层
- MAC VLAN
五层模型
- 应用层
- 传输层
- 网络层
- 数据链路层
- 物理层
各协议作用
- DNS:域名解析
- HTTP:超文本传输
- FTP:文本传输协议
- PRC: 远程过程调用协议
- TCP:传输控制协议
- UDP:用户数据报协议
- IP: 互联协议
- ARP:地址解析协议,实现通过IP地址得知其物理地址。
- MAC:MAC是物理地址
TCP/UDP
区别
- TCP是面向连接的,UDP是无连接的;
- UDP发送数据之前不需要建立连接
- TCP是可靠的,UDP不可靠;
- UDP接收方收到报文后,不需要给出任何确认,所以UDP不可靠
- TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多;
- TCP是面向字节流的,UDP是面向报文的;
什么时候选择TCP,什么时候选UDP?
对某些实时性要求比较高的情况,选择UDP,比如游戏,媒体通信,实时视频流(直播),即使出现传输错误也可以容忍;其它大部分情况下,HTTP都是用TCP,因为要求传输的内容可靠,不出现丢失
HTTP可以使用UDP吗?
HTTP不可以使用UDP,HTTP需要基于可靠的传输协议,而UDP不可靠
TCP如何保证可靠传输?
- 数据包校验:数据会被分割成TCP认为最适合发送的数据包、然后对每一个包进行编号,接收方接收后会按照序号拼接,检验和可以检测数据传输过程中的任何变化,如果发生变化就丢弃该报文段。同时TCP接收端也会主动丢弃掉重复的数据。
- 应答机制:接收方收到数据之后,会发送一个确认(通常延迟几分之一秒)
- 超时重发:发送方发出数据之后,启动一个定时器,超时未收到接收方的确认,则重新发送这个数据;
- 流量控制:确保接收端能够接收发送方的数据而不会缓冲区溢出
- 拥塞控制:解决数据传输拥塞问题
超时重传
- RTT(Round Trip Time) 一个连接的往返时间,即数据发送时刻到接收到确认的时刻的差值;
- RTO(Retransmission TimeOut)即重传超时时间。即从数据发送时刻算起,超过这个时间便执行重传。
- 由于网络波动的不确定性,每个RTT都是动态变化的,所以RTO也应随着RTT动态变化
流量控制
流量控制是为了控制发送方发送速率,保证接收方来得及接收。
接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。
实际上,为了避免此问题的产生,发送端主机会时不时的发送一个叫做窗口探测的数据段,此数据段仅包含一个字节来获取最新的窗口大小信息。
拥塞控制
如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。
TCP 主要通过四个算法来进行拥塞控制:
慢开始、拥塞避免、快重传、快恢复。
- 慢启动:刚开始发送数据时,拥塞窗口大小呈指数增加,达到门限值之后进入拥塞避免阶段;
- 拥塞避免:当拥塞窗口的大小达到慢开始门限时,开始执行拥塞避免算法,拥塞窗口大小不再指数增加,而是线性增加;
- 在慢启动或者拥塞避免阶段只要发送方没有收到确认就认为拥塞了,就要把慢开始门限值设置为当前值的一半,然后拥塞窗口设为1,重新执行慢开始+拥塞避免
- 快重传就是接收方发现数据丢失后,立即发送重复确认,当发送方连续收到三个重复确认时,立即重新重传丢失的数据
- 快恢复就是发送方连续收到三个重复确认时,把门限减半,此时不执行慢开始算法,而是将拥塞窗口大小设为门限的大小,然后执行拥塞避免算法
滑动窗口
**在任意时刻,发送方和接收方都维持了一个允许发送/接收的帧序号,称为滑动窗口。**发送方称为发送窗口,接收方称为接收窗口。
滑动窗口以字节为单位。通过发送窗口向对方发送数据时,在没有收到对方的确认情况下,发送方可以连续把窗口内的数据都发出去。当收到对方的确认号在窗口内时,发送方就可以使窗口向前滑动。凡是已经发送过的数据,在没有收到确认前都必须缓存在窗口中,以便超时重传时使用。在实际通信过程中,窗口大小是可以根据接收能力进行动态调整的(流量控制)。
TCP通过它来进行流量控制。有三种协议
-
1比特滑动窗口
- 发送窗口=1,接收窗口=1。
- 发送方每发送一帧就要停下来等待对方接收并确认返回后才能继续发送下一帧。
- 传输效率低。
-
后退n协议
- 发送窗口>1,接收窗口=1。
- 发送在发完一帧后,不停下来等待应答,而是连续发送若干个数据桢,即使在连续发送过程中收到了接收方的应答帧,也可以继续发送。且发送每发送完一个数据桢都要设置一个超时定时器。只要在所设置的超时时间内仍然没有确认帧,就要重新发送。
- 接收方若发现错误就不再接收后续的帧,即使接收到正确的帧,这显然是一种浪费。
-
选择重传协议
- 发送窗口>1,接收窗口>1。
- 在数据传输过程中,**若接收方收到了错误帧,此时不会停止接收后续的帧,而是将后续的帧保存在一个缓冲区中,同时要求发送方立即重新发送出错的帧。**一旦收到重新传过来的帧,就可以将缓冲区的帧按照正确的顺序进行处理。
- 减少浪费。
什么是零窗口(接收窗口为0时会怎样)?
如果接收方没有能力接收数据,就会将接收窗口设置为0,这时发送方必须暂停发送数据,但是会启动一个持续计时器(persistence timer),到期后发送一个大小为1字节的探测数据包,以查看接收窗口状态。如果接收方能够接收数据,就会在返回的报文中更新接收窗口大小,恢复数据传送。
三次握手与四次挥手(重要!)
三次握手
过程:
- 第一次握手:Client将SYN置1,随机产生一个初始序列号seq发送给Server,进入SYN_SENT状态;
- 第二次握手:Server收到Client的SYN=1之后,知道客户端请求建立连接,将自己的SYN置1,ACK置1,产生一个acknowledge number=sequence number+1,并随机产生一个自己的初始序列号,发送给客户端;进入SYN_RCVD状态;
- 第三次握手:客户端检查acknowledge number是否为序列号+1,ACK是否为1,检查正确之后将自己的ACK置为1,产生一个acknowledge number=服务器发的序列号+1,发送给服务器;进入ESTABLISHED状态;服务器检查ACK为1和acknowledge number为序列号+1之后,也进入ESTABLISHED状态;完成三次握手,连接建立。
相关问题
TCP建立连接可以两次握手吗?为什么?
不可以。有两个原因:
首先,可能会出现已失效的连接请求报文段又传到了服务器端。
其次,两次握手无法保证Client正确接收第二次握手的报文(Server无法确认Client是否收到),也无法保证Client和Server之间成功互换初始序列号。
可以采用四次握手吗?为什么?
可以。但是会降低传输的效率。
四次握手是指:第二次握手:Server只发送ACK和acknowledge number;而Server的SYN和初始序列号在第三次握手时发送;原来协议中的第三次握手变为第四次握手。出于优化目的,四次握手中的二、三可以合并。
第三次握手中,如果客户端的ACK未送达服务器,会怎样?
- Server端: 由于Server没有收到ACK确认,因此会重发之前的SYN+ACK(默认重发五次,之后自动关闭连接进入CLOSED状态),Client收到后会重新传ACK给Server。
- Client端,两种情况: 在Server进行超时重发的过程中,如果Client向服务器发送数据,数据头部的ACK是为1的,所以服务器收到数据之后会读取 ACK number,进入 establish 状态 在Server进入CLOSED状态之后,如果Client向服务器发送数据,服务器会以RST包应答。
如果已经建立了连接,但客户端出现了故障怎么办?
服务器每收到一次客户端的请求后都会重新复位一个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
四次挥手
过程:
- 第一次挥手:Client将FIN置为1,发送一个序列号seq给Server;进入FIN_WAIT_1状态;
- 第二次挥手:Server收到FIN之后,发送一个ACK=1,acknowledge number=收到的序列号+1;进入CLOSE_WAIT状态。此时客户端已经没有要发送的数据了,但仍可以接受服务器发来的数据。
- 第三次挥手:Server将FIN置1,发送一个序列号给Client;进入LAST_ACK状态;
- 第四次挥手:Client收到服务器的FIN后,进入TIME_WAIT状态;接着将ACK置1,发送一个acknowledge number=序列号+1给服务器;服务器收到后,确认acknowledge number后,变为CLOSED状态,不再向客户端发送数据。客户端等待2*MSL(报文段最长寿命)时间后,也进入CLOSED状态。完成四次挥手。
为什么不能把服务器发送的ACK和FIN合并起来,变成三次挥手(CLOSE_WAIT状态意义是什么)?
因为服务器收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复ACK,表示接收到了断开连接的请求。等到数据发完之后再发FIN,断开服务器到客户端的数据传送。
如果第二次挥手时服务器的ACK没有送达客户端,会怎样?
客户端没有收到ACK确认,会重新发送FIN请求。
客户端TIME_WAIT状态的意义是什么?(第四次挥手客户端直接Closed会怎样?)
第四次挥手时,客户端发送给服务器的ACK有可能丢失,TIME_WAIT状态就是用来重发可能丢失的ACK报文。如果Server没有收到ACK,就会重发FIN,如果Client在2*MSL的时间内收到了FIN,就会重新发送ACK并再次等待2MSL,防止Server没有收到ACK而不断重发FIN。
MSL(Maximum Segment Lifetime),指一个片段在网络中最大的存活时间
为什么等待2MSL?
- 保证客户端发送的最后一个ACK报文能够达到服务器
- 等待2MSL就可以使本连接持续的时间所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求的报文段。
TCP粘包
什么是 TCP 沾包
粘包发生在发送或接收缓冲区中,应用程序从缓冲区中取数据是整个缓冲区中有多少取多少,那么就有可能第一个数据的尾部和第二个数据的头部同时存在缓冲区,而 TCP 是流式的,数据无边界,这时发生粘包。
TCP 粘包的产生
发送方引起的粘包:是由 TCP 协议本身造成的,TCP 为提高传输效率,发送方往往要收集到足够多的数据后才发送。若连续几次发送的数据都很少,通常 TCP 会根据 Nagle 优化算法把这些较小的数据包进行合并一起发送,这样接收方就收到了粘包数据。
接收方引起的粘包:是由于接收方用户进程不及时接收数据,从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,这时会出现一个问题,就是我们在程序中调用的读取数据函数不能及时的把缓冲区中的数据拿出来,而下一个数据又到来并有一部分放入的缓冲区末尾,等我们读取数据时就是一个粘包;(放数据的速度 > 应用层拿数据速度) 。
TCP 粘包解决方案
**解决发送方粘包 **
- 发送产生是因为Nagle算法合并小数据包,那么可以禁用掉该算法;
- TCP 提供了强制数据立即传送的操作指令 push,当填入数据后调用操作指令就可以立即将数据发送,而不必等待发送缓冲区填充自动发送;
- 数据包中加头部信息,头部信息为整个数据的长度(最广泛最常用);
解决接收方粘包
- 解析数据包头部信息,根据长度来接收;
- 自定义数据格式:在数据中放入开始、结束标识;解析时根据格式抓取数据,缺点是数据内不能含有开始或结束标识;
- 短连接传输,建立一次连接只传输一次数据就关闭;(不推荐)
HTTP/HTTPS
HTTP和HTTPS区别?
- HTTP运行于TCP之上,明文传输,客户端和服务器都无法验证对方的身份;HTTPS运行于SSL之上,SSL运行于TCP之上,是添加了加密和认证机制的HTTP
- HTTP使用80端口,HTTPS使用443端口
- HTTPS消耗更多资源,而且需要证书,证书需要购买
HTTP1.0和HTTP1.1的区别
- HTTP1.1默认使用长连接
- HTTP1.1新增了一些错误状态码
- HTTP1.1引入了更多的缓存控制策略
- HTTP1.1进行了一些带宽的优化
HTTP长连接、短连接
- HTTP/1.0中默认使用短连接,客户端和服务器每进行一次HTTP操作就要进行一次连接,如果访问的HTTP资源中包含其他Web资源,对于每一个这样的资源都要去重新建立一个HTTP会话。
- HTTP1.1以上默认使用长连接,一个网页打开后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。
- 长连接不会永久保持,有一个保持时间
常见状态码
-
2xx状态码:操作成功
- 200 OK
-
3xx状态码:重定向。
- 301 永久重定向
- 302暂时重定向
-
4xx状态码:客户端错误。
- 400 Bad Request 错误的请求
- 401 Unauthorized 用户没有访问权限
- 403 Forbidden 服务器拒绝请求
- 404 Not Found;未找到资源
-
5xx状态码:服务端错误。
- 500服务器内部错误
- 501服务不可用
GET与POST的区别?
- GET是幂等的,即读取同一个资源,总是得到相同的数据,POST不是幂等的;
- GET一般用于从服务器获取资源,而POST有可能改变服务器上的资源;
- 请求形式上:GET请求的数据附在URL之后,在HTTP请求头中;POST请求的数据在请求体中;
- 安全性:GET请求可被缓存、收藏、保留到历史记录,且其请求数据明文出现在URL中。POST的参数不会被保存,安全性相对较高;
- GET只允许ASCII字符,POST对数据类型没有要求,也允许二进制数据;
- GET的长度有限制(操作系统或者浏览器),而POST数据大小无限制
HTTPS验证流程
-
客户端发起一个http请求,连接到服务器的443端口。
-
服务端把自己的信息以数字证书的形式返回给客户端。
-
验证证书的合法性
-
生成随机密码(RSA签名)
-
生成对称加密算法
HTTPS通信过程/连接过程
- 客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。
- Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。
- 客户端的浏览器与Web服务器开始协商SSL/TLS连接的安全等级,也就是信息加密的等级。
- 客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。
- Web服务器利用自己的私钥解密出会话密钥。
- Web服务器利用会话密钥加密与客户端之间的通信。
HTTP缓存机制
- 缓存介绍: 缓存就是让同一份资源不再发起请求,降低网络压力和资源数量,从而让网页加载更快。网络请求不稳定加剧了网页加载的不稳定性,所以需要缓存。一般来说,js、css、img等静态资源可以被缓存
- http缓存策略:
- 强制缓存:浏览器不会像服务器发送任何请求,直接从本地缓存中读取文件并返回Status Code: 200 OK
- 协商缓存:向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源;
重定向会对资源的缓存有影响吗
dns解析过程
- client 提出域名解析请求,并发送给本地域名服务器
- 本地域名解析服务器收到请求,先查询缓存,若没有缓存,就去根域名服务器找
- 根域名服务器告诉本地域名服务器一个主域名服务器的地址
- 本地域名服务器又去找主域名服务器,若主域名服务器没有缓存,则告诉一个具体的解析服务器地址
- 本地域名服务器最后去找解析服务器地址,获取到解析结果
HTTPS加密过程
-
https是基于tcp协议的,客户端先会和服务端发起链接建立
-
接着服务端会把它的证书返回给客户端,证书里面包括公钥S.pub、颁发机构和有效期等信息
-
拿到的证书可以通过浏览器内置的根证书,验证其合法性
-
客户端生成随机的对称加密秘钥Z,通过服务端的公钥S.pub加密发给服务端
-
客户端和服务端通过对称秘钥Z加密数据来进行http通信
证书
证书的一个作用是用来证明作为通信一方的服务器是否规范,另外一个作用是可确认对方服务器背后运营的企业是否真实存在。比如SSL证书。
《图解HTTP》提到证书:
- 数字证书
- SSL 证书
- 自签名证书
- 用以确认客户端的客户端证书
在浏览器中输入url地址到显示主页的过程
- 浏览器查找域名的IP地址,这时要使用DNS解析
- 浏览器和服务器建立TCP连接,这时要使用TCP和IP协议
- IP数据包在路由器之间传输需要使用OSPF协议进行路由选择
- 路由器与服务器通信时,要将ip地址转成MAC地址,需要使用ARP协议
- 浏览器向服务器发送HTTP请求,这时需要使用HTTP协议
- 服务器处理请求
- 服务器返回一个HTML响应
- 浏览器开始显示HTML
cookie与session
存储位置不同
-
cookie的数据信息存放在客户端浏览器上。
-
session的数据信息存放在服务器上。
存储容量不同
- 单个cookie保存的数据<=4KB,一个站点最多保存20个Cookie。
- 对于session来说并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东西,并且设置session删除机制。
存储方式不同
- cookie中只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据。
- session中能够存储任何类型的数据
隐私策略不同
- cookie对客户端是可见的,别有用心的人可以分析存放在本地的cookie并进行cookie欺骗,所以它是不安全的。
- session存储在服务器上,对客户端是透明的,不存在敏感信息泄漏的风险。
有效期上不同
- 开发可以通过设置cookie的属性,达到使cookie长期有效的效果。
- session依赖于名为JSESSIONID的cookie,而cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该session就会失效,因而session不能达到长期有效的效果。
服务器压力不同
- cookie保管在客户端,不占用服务器资源。对于并发用户十分多的网站,cookie是很好的选择。
- session是保管在服务器端的,每个用户都会产生一个session。假如并发访问的用户十分多,会产生十分多的session,耗费大量的内存。
跨域支持上不同
- cookie支持跨域名访问。
- session不支持跨域名访问。
请求重定向与请求转发的区别
请求重定向
- 重定向是指当浏览器请求一个 URL 时,服务器返回一个重定向指令,告诉浏览器地址已经变了,麻烦使用新的 URL 再重新发送新请求。
请求转发
- 请求转发是指内部转发。当一个 Servlet 处理请求的时候,它可以决定自己不继续处理,而是转发给另一个 Servlet 处理。
URL/URI
- URI(统一资源标识符)是 Uniform Resource Identifier 的缩写。它主要用于定位某一类特定的资源而设计,用来唯一标识互联网上的资源,并不具备定位该资源的能力。它包括 URL 和 URN。
- URL(统一资源定位符)是 Uniform Resource Locator 的缩写。它用来找到资源所在的位置,并且去访问和得到资源。
- URL 是一种具体的 URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。