赞
踩
各层之间是独立的。每一层并不需要知道它的下一层是如何实现的。
灵活性好。当任何一层发生变化时(例如由于技术的变化),只要层间接口关系保持不变,则其他层都不受影响。
当某层提供的服务不再需要时可以将这层取消。
结构上可分割开。各层都可以采用最合适的技术来实现。
易于实现和维护。
应用层:
协议:HTTP、FTP、SMTP、DNS
概念精简:提供应用之间通信,定义了运行在不同系统上的应用程序
如何相互传递报文,并且他定义了进程交换的报文类型。报文语法。字段含义、何时发怎么发。
传输层:
协议:TCP。UDP
概念精简:属于主机间不同进程的通信,向应用层提供通信服务,屏蔽下面网络细节(当使用TCP是可靠的,提供可靠承诺)
网络层:
协议:IP、ICMP
概念精简:主要是负责主机之间的通讯,向传输层提供无连接的数据包服务。
特点:
HTTP0.9就是协议原型,只支持GET方法只有HTML对象,到了HTTP1.0增加了不同的方法POST和HEAD,支持多媒体对象, 但是1.0版本的工作方式是每次TCP连接只能发送一个请求,当服务器响应后就会关闭这次连接,下一个请求需要再次建立TCP连接,就是不支持keepalive。HTTP1.1默认是长连接,加入缓存处理、管道化等,到了HTTP2.0就有多路复用、头部压缩、服务端推送等特点。
Keep-alive长连接为了解决在提供服务前客户端与服务端需要建立连接(TCP:三次握手、断开四次挥手),这种频繁的连接建立与释放需要占据很大资源(时间与计算成本)。
(1)多路复用:
做到同一个连接并发处理多个请求。
还有这个二进制分帧,通信是以帧为单位
多请求并行不依赖多tcp连接
并行在一个TCP连接交互多种类型信息
在keep-alive里有个问题就是如果能知道每个repose与其对应的request的话,并发的请求可以只需要一次TCP连接,这也就是http2.0实现的多路复用。
(2)头部压缩:维护了静态字典实现,以及通过哈夫曼编码对字符压缩。
HTTP请求和响应中,状态行和请求/响应头都是些信息字段,并没有真正的数据,因此在2.0版本中将所有的信息字段建立一张表,为表中的每个字段建立索引,客户端和服务端共同使用这个表,他们之间就以索引号来表示信息字段,这样就避免了1.0旧版本的重复繁琐的字段,并以压缩的方式传输,提高利用率。
(3)服务端推送:主动向客户端推送数据,
(4)http2.0 适用于 https 场景,因为其在 http 和 tcp 中间加了一层 ssl 层
HTTP报文结构:
1)请求报文结构:
请求头是键值对
2)应答报文结构:
请求方法:本质是对服务器资源进行增删改查等操作,通过定义不同方法实现不同操作
GET:比较常用,客户端请求服务器发送某个资源(HTTP0.9就支持了)客户端GET到数据
HEAD:和GET相似,但是服务器只返回首部,不返回内容,常用于检查状态
POST:向服务器写入数据(推送的意思)
TRACE(吹死):观察请求报文到达服务器的最终样子(现在WEB服务架构比较复杂,一个请求会经过很多层,比如代理,防火墙之类的,然后最终到达服务器,每个中间节点都有可能改变原始HTTP请求,TRACE可以了解到达最终服务端的样子)
PUT:与GET相反,类似POST(POST用于写入账号密码之类的),向服务器写入资源(文件资源以及多媒体资源等等)
DELETE:请求服务器删除URL所指定的资源
OPTIONS:在中间服务中使用,比如代理,防火墙,转发服务等,返回资源可以操作的一些方法包括以上所有方法
幂等:
幂等操作:多次执行产生的影响与执行一次产生的影响相同:
幂等函数:使用相同参数重复执行,能获得相等结果的函数
POST不是幂等,因为取决于后台实现
(需要自己查一下)
常见的状态码:
定位:通过状态码了解具体是哪一个部位发生问题
安全传输模型:
简单说就是:用户A传输数据前加密,用户B解密得到信息。
蜜钥:分对对称秘钥与非对称秘钥,在明文转换为密文或者解密的算法中输入的参数
古典密码学:
置换密码表,代换密码表。
局限性:可以通过字频分析找出映射关系进行破译。
**对称加密:**两边秘钥相同。
具体算法有:DES算法、3DES算法、AES算法(下一代加密算法标砖-速度快安全级别更高)
非对称加密:两边秘钥不同。(但是有一定的数学关系的一组秘钥,分私钥与公钥)
具体算法有:RSA算法(最具有影响力,两个大的素数相乘,在因式分解结果)、ECC算法(椭圆加密)、DH算法
散列算法(哈希函数):有MD5算法等
可以把数据压缩,把数据量变小,将数据的格式保留下来。
哈希碰撞:如果多个原文哈希后得到一个密文
安全性:
如果恶意用户得到泄露后的数据库(拖库),且了解用了那种散列算法比如MD5,要是他自身有庞大的哈希散列结果数据,他只需要一一匹配就能得到明文。
解决方法:加盐操作:原文加上自定义字符后进行哈希加密。
散列算法不能逆向解密,只能加密不能解密,所以不能称之为加密算法
HTTP:不安全,复杂度低效率高,端口一般是80
HTTPS:安全,复杂度高效率低,端口是443
HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为客户端和服务器之间的通信加密。
消息认证码(MAC)+数字摘要:保护数据完整性,发送数据的时候会附加消息认证码(MAC),MAC能够查知报文是否遭到篡改,从而保护报文的完整性。
数字摘要就是采用单向Hash函数将需要加密的明文摘要成一串固定长度的密文,这一串密文又称为数字指纹,它有固定的长度,而且不同的密文摘要成密文,其结构总是不同的.而同样的明文其摘要必定一致,通过这种方法对比原文和摘要,就能够验证数据是否遭到修改。如SHA,MD5加密算法.
TLS(传输层安全性协议),保证数据安全与完整,对传输层数据进行加密后传输。(非对称加密)
数字证书:可信组织颁发给特定对象的认证,指的是在互联网通讯中标志身份信息的数字认证。
(使用非对称算法生成对称秘钥)
HTTPS建立连接过程:先通过443端口建立TCP连接,在通过SSL安全参数握手,然后双方拿到对称秘钥,就能收发数据啦!
SSL安全参数握手过程:
1.在客户端生成随机数R1,把随机数R1、协议版本以及加密算法信息发给服务端
2.在服务端生成随机数R2,把随机数R2,数字证书以及确定加密算法信息发给客户端
3.客户端确认证书有效性(TLS向颁发证书的机构)、生成随机数R3,根据会话密钥算法使用R1、R2、R3生成会话密钥。并且使用服务器的公钥加密随机数R3,把加后的随机数R3发送给服务端。
4.服务器用私钥解密客户端发过来的随机数R3,根据会话密钥算法使用R1、R2、R3生成会话密钥
6.这时候双方都有随机数R1、R2、R3,和相同的算法生成的对称秘钥
7.就可以通讯了,(双方生成的秘钥没有经过传输)
通过MD5加到消息后面验证数据的完整性。
DNS域名服务是什么:把域名(就是网址www.baidu.com)翻译成IP地址的服务。是一个存储域名和IP地址映射关系的分布式数据库。
域名由点、字母、数字组成,点来分割不同的域,域名分为顶级域名,二级域名,三级域名。
如:www.lcy.com ——>三级域名.二级域名.顶级域名
**DNS工作原理:**DNS过程发生在客户端,查询域名的IP地址是通过迭代查询或者递归查询,(先查询本地缓存)
迭代查询
com
后缀,将顶级服务器IP告诉给本地服务器递归查询
浏览器查询缓存,是否有百度的ip,如果有结束
hosts文件中是否有百度的ip地址,如果有结束
如果本地DNS有百度的ip地址,如果有,本地DNS将其返回给请求主机,然后结束
根服务器根据com
后缀,将请求转发给顶级域名服务器
顶级域名服务器查询自己的权威DNS服务器
权威DNS域名服务器查询到百度的IP,将结果返回给顶级,顶级返回给根,根返回给本地,本地返回给请求主机,结束。
被攻击后会有比如将正常站点解析成恶意页面。错误域名解析到非正常或者纠错页面都是
**DNS劫持:**拿到网络运营商把域名的NS记录解析到攻击者控制的DNS服务器,给用户返回恶意页面(控制服务器)
**DNS欺骗:**攻击者冒充权威域名服务器,进行地址替换。(顶替服务器)
**DDoS攻击:**DNS本质上是要在物理机上运行,可是物理设备有容量承载极限,超过极限就会宕机,
DDoS是一种网络攻击,原理是消耗系统资源使服务中断。
**防范DNS劫持:**不使用自动获取DNS服务器,要指定DNS服务器。(选取权威的DNS服务)
udp协议:
协议头有:源端口号、目的端口号、UDP长度、UDP校验和(判断数据是否出错)(都是16位)
TCP协议:
TCP协议头部字段并不是固定只有二十个字节、
1.序号:4个字节,每一个字节都有唯一的序号(表示报文段数据的第一个字节的序号)
2.确认号:4个字节,期待收到对方下一个报文的第一个数据字节序号(若确认号为N,则序号N-1为止的所有数据都已经确认收到,期待发送序号N的报文)
3.控制位:6个比特位。
4.窗口:2字节,准许对方发送的数据量大小。因为数据缓冲空间优先,不能无限缓存数据。
UDP vs TCP:
(1) TCP提供可靠的有连接服务,UDP提供不可靠无连接服务:
在TCP协议中使用了应答和重传机制,使得每一个信息都能保证到达,是可靠的。而UDP是尽力传送,没有应答和重传机制,UDP只是将信息发送出去,对方收不收到也不进行应答。所以UDP协议是不可靠的。但是对于一些实时性要求高的场景(比如电话会议)就需要UDP,因为远程视频的话,你丢一些数据(例如像素)并不影响视频的内容。
(2) TCP是面向字节流的,UDP是面向报文的:
TCP基于流的传输,表示TCP不认为消息是一条一条的,是不保护消息边界的,UDP面向报文,是有保护消息边界的,接收方一次只能接受一条独立的消息,所以UDP不存在粘包。
(3) TCP只有一对一的传输方式,而UDP不仅可以一对一,还可以一对多,多对多:
UDP 不止支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能。
TCP不能一对多的原因是:TCP通信前要跟一台主机进行三次握手连接,因此TCP不能一对多。
(4) UDP的头部开销小,TCP的头部开销大;
UDP的头部很小,只有8个字节。相比TCP至少20个字节,UDP头部要小得多。
(5) TCP会产生粘包问题,UDP会产生丢包问题:
为什么会发生粘包?
因为TCP是面向连接的流式传输协议,所以用TCP进行数据传输的时候并不是以数据包的形式推送的,而是流的形式。但是实际开发的时候,数据大多都是以数据包的形式发送的,并且每次数据包的大小可能都不一样。并且每个数据包都有我们自定义的数据格式,接收端基于这个格式进行解析,在进行逻辑处理。但是接收端可能一次性接收到不止一个数据包,也不能以一种固定的格式拆分数据包,所以就会有多个数据包沾黏在一起的现象。
TCP默认使用Nagle算法,只有收到前一个分组的确认后,才能发送下一个分组,等待确认的过程中,发送端缓冲区就可能将多个较小的分组打包在一起发送,就是粘包。
我认为TCP本身就是流式传输协议,黏包问题他是我们的一个特殊需求。
黏包解决方案:
1 使用标准的应用层协议(比如:http、https)来封装要传输的不定长的数据包
2 在每条数据的尾部添加特殊字符,如果遇到特殊字符,代表当条数据接收完毕了
有缺陷:效率低,需要一个字节一个字节接收,接收一个字节判断一次,判断是不是那个特殊字符串
3 在发送数据块之前,在数据块最前边添加一个固定大小的数据头,这时候数据由两部分组成:数据头 + 数据块
数据头:存储当前数据包的总字节数,接收端先接收数据头,然后在根据数据头接收对应大小的字节接收数据块
数据块:当前数据包的内容
由于UDP是没有应答和重传机制,因此包很容易传丢。
主要丢包原因:
接收端处理时间过长导致丢包:对于这种情况可以修改接收端,将包接收后存入一个缓冲区,然后迅速返回继续recv。
发送的包巨大丢包:虽然send方法会帮你做大包切割成小包发送的事情,但包太大也不行。例如超过50K的一个udp包,不切割直接通过send方法发送也会导致这个包丢失。这种情况需要切割成小包再逐个send。
发送的包较大,超过接受者缓存导致丢包:包超过最大传输单元数倍,几个大的udp包可能会超过接收者的缓冲,导致丢包。这种情况可以设置socket接收缓冲。以前遇到过这种问题,我把接收缓冲设置成64K就解决了。
发送的包频率太快:虽然每个包的大小都小于mtu size 但是频率太快,例如40多个mut size的包连续发送中间不sleep,也有可能导致丢包。
三次握手的过程 :
首先客户端向服务器端发送连接请求,其中标志位为SYN,初始化 序列号(seq)为随机数x。然后客户端就会从CLOSE状态进入 SYNC-SENT状态。 服务器端原本处于LISTEN状态,在收到客户端发送的连接请求后,可以知道客户端发送消息的能力和 自己接受消息的能力是正常的,然后发送标志位是SYN和ACK的报文作为响应,初始化seq序列号为随机数y,ack确认序号为 x + 1。随后服务器端进入 SYNC-RECV状态。 客户端收到服务器端的报文后,就能知道自己和服务器收发消息的能力都是正常的,然后发送标志位是ACK的报文,seq序列号为x + 1,ack确认序号为 y + 1。随后客户端进入 established状态。 服务器端收到ACK报文后,得知自己和客户端的消息收发能力都是正常的,从而结束SYNC-RECV状 态,进入established状态,TCP连接建立。
为什么要握手?
三次握手的本质是双方确认对方的消息收发能力,以及同步双方的序列号和确认号、交换TCP窗口大小等信息。
为什么不能是两次握手?
1、两次握手不能确定双方收发消息的能力 ,如果是两次握手,那么客户端能确定自己向服务器端的收发能力都是正常的,但是服务器端却只能确定客户端的发送能力和自己的接受能力是正常的,无法确定客户端的接受能力和自己的发送能力是否正常,连接不一定可靠。
2、第一次握手出问题 - 网络中滞留: 如果第一次握手的SYN报文在网络中滞留,导致客户端重发SYN报文建立连接,而之前滞留的SYN报 文直到连接断开后才到达服务器端,服务器端误以为客户端又有建立连接的请求,会通过第二次握手 建立连接,但此时客户端处于CLOSED状态,无法接收第二次握手的报文,也不会发送数据,而服务器则处于established状态,一直在空等。
3、第二次握手出问题 - 报文丢失:如果服务器端在发送ACK报文(第二次握手)后在处于ESTABLISHED状态,此时如果该ACK报文丢 失,则客户端会一直处于等待状态,不会开始传输数据,直到超过重传时间后,客户端才会重新发起 第一次握手,这时已经开启的连接一直处于空闲状态,同时另外又会尝试建立一个新的连接,浪费通信资源。
为什么不是四次握手?
从双方确认收发能力的角度说 三次握手足够确认双方收发能力了 第一次握手:服务器确认自己收 和 对方发 的能力 第二次握手:客户端确认自己收发 和 对方收发 的能力 第三次握手:服务器确认自己收发 和 对方收发 的能力
三次握手过程中可以携带数据吗?
第一次和第二次握手不可以,第三次握手可以。
第一次握手不可以携带数据是为了防止SYN攻击,如果SYN报文允许携带数据,那么服务器端就要消 耗大量资源去接受携带数据的大型SYN报文。
第二次握手因为服务器端只是处于SYNC-RECV状态而不是ESTABLISHED状态,无法确定对方的接收能力和自己的发送能力,所以不能携带数据。
第三次握手可以携带数据,是因为此时客户端已经处于ESTABLEISHED状态,对于它来说已经建立起 了连接,已经确定了双方的收发能力都是正常的,所以可以携带数据。
服务器端收到客户端发来的SYN报文后会进入SYNC-RECV状态,这个时候的连接还没有完全建立,这种状态下的连接会被放在半连接队列中。全连接队列存放的是完成三次握手的连接,全连接队列满了以后会有丢包的可能。 服务器端发送SYN+ACK报文后如果没有收到客户端的ACK报文,则会不断重发报文,当重发次数超过最大重传次数(默认5次)后,该连接会从半连接队列中移除。但此时客户端可能是已经发送 ACK报文的,只是ACK报文丢失,因此客户端处于ESTABLISHED状态,若之后客户端开始发送数据, 那么处于CLOSED状态的服务器端则会发送RST报文作为响应。
1、首先讲一下半连接状态 服务器在发出第二次握手后,进入SYNC-RECV状态,此时连接处于半连接状态,只有收到第三次握手 后才会进入全连接状态。
2、SYN功击就是客户端伪造大量虚假IP地址,向服务器端不断发送SYN包,服务器则不断回复,等待客户端第三次握手,但由于IP地址是虚假的,所以根本等不到第三次握手,所以服务器会一 直重传SYN+ACK包,同时半连接队列会被这种连接撑满,正常的SYN请求因为队满而被丢弃。
常见的防御SYN攻击的方法有: 缩短超时时间,增加最大半连接数,过滤网关
四次挥手发生在TCP断开连接的时候,这一过程不区分客户端和服务端,而是按照主动发起断开连接的端作为主动端,另一端为被动端。
主动端一开始处于ESTABLISHED状态,主动发起第一次挥手,向被动端发送一个标志位为FIN的报文,序列号seq为u,随后主动端处于FIN-WAIT-1状态,停止向被动端发送数据。 被动端接受到FIN报文后,结束ESTABLISHED状态,发起第二次挥手,回复一个标志位为ACK的报文,序列号seq为v,确认号ack为u + 1,随后进入CLOSE-WAIT状态。 主动端收到被动端的ACK报文后,结束FIN-WAIT-1状态,进入FIN-WAIT-2状态。 被动端发出ACK报文后,会将剩下的数据传输给主动端,传输完成后CLOSE-WAIT状态结束,发起第 三次挥手,发送一个标志位是FIN和ACK的报文,序列号seq是w,确认序号ack是u + 1,随后被动端进入LAST-ACK状态,停止向主动端发送数据。 主动端收到被动端发来的报文后,结束FIN-WAIT-2状态,发起第四次握手,发送一个标志位是ACK的报文,序列号seq是u + 1,确认序号ack是w + 1,随后进入TIME-WAIT状态。 主动端会在TIME-WAIT状态下等待 2个MSL的时间,被动端接收到主动端的第四次挥手报文后进入 CLOSED状态,主动端等待2 MSL时间后,结束TIME-WAIT状态,进入CLOSED状态,完成四次挥 手,但若是在TIME-WAIT期间收到了被动端重传的第三次握手,那么说明第四次握手在网络中丢失 了,此时被动端还没有关闭,于是主动端也需要重新发起第四次握手,并且重置TIME-WAIT计时器。
为什么要四次挥手?
因为TCP连接是全双工工作的,断开连接是需要从两个方向上都断开的。 因为四次挥手中,开始的两次挥手是用于主动端通知被动端断开连接的请求,说明主动端此时已经没 有发送数据的需求了,但是被动端可能还有没发送完的数据,所以要等被动端也没有发送数据的需求 了,才能通过后两次挥手完成整个过程。
CLOSE-WAIT状态的意义?
保证被动端把没发送完的数据,发送完,再断开连接。
TIME-WAIT状态的意义 ?
1、保证第四次挥手可以到达被动端,若没有这个阶段,而是发起第四次挥手后直接进入CLOSED状 态,那么万一第四次挥手在网络中丢失,被动端就会重传第三次挥手,此时处于CLOSED状态的主动 端就会发送一个RST报文给被动端,这会使对方以为有错误发生,但其实只是正常的关闭连接。
2、TIME-WAIT状态等待的2MSL也保证了断开连接时,连接中没有残留的数据包。
TIME-WAIT为什么是2MSL(最长报文段寿命,1MSL建议两分钟)?
1、MSL是最大报文生命周期,就是一个报文被丢弃前在网络中的最大存活时间。
因为网络是不可靠的,将TIME-WAIT时间设置为2MSL,保证了在第一个MSL时间结束后,第四次挥手要么达到被动 端,要么在网络中丢失,但此时我们无法确定究竟是哪一种情况,如果顺利达到被动端,那么被动端 将不会发送第三次回收的重传报文,如果在网络中丢失,那么被动端最晚会在第一个MSL结束时刻重传第三次挥手,主动端将最晚在2MSL时间内收到该重传报文。
2、还可以保证本次连接持续时间内产生的所有报文都从网络中消失。
TIME-WAIT状态会导致什么问题?
1、服务器 在高并发短连接的场景下,服务器处理完请求后作为主动端发起四次挥手,此时服务端上会有大量的 连接处于TIME-WAIT状态,占用有限的连接资源,而连接是有上限的,这会导致正常的连接失败。
2、客户端 客户端TIME-WAIT状态过多会导致端口被占用,被占满就无法创建新的连接
有很多TIME-WAIT状态该如何解决?
1、并发量不高的情况下 可以采用长连接,避免频繁的连接与断开,自然减少了TIME-WAIT状态的时间。
2、并发量高的场景下 可以设置SO_REUSERADDR套接字选项来通知内核,如果端口被占用,但TCP连接处于TIME-WAIT状 态时可以重用端口。
TIME_WAIT 是服务器端的状态?还是客户端的状态?
TIME-WAIT是主动发起断开连接请求的一方的状态,服务器和客户端都可以处于这个状态。 但是一般服务器不会主动断开连接,因为这样会使服务器这边存在大量TIME-WAIT状态的连接,浪费连接资源。 一般都是浏览通过指定 keepalive 来重用连接,避免频繁的TIME-WAIT状态,以及由浏览器主动断开 连接来缓解这个问题。
有很多CLOSED-WAIT状态该如何解决?
首先检查是不是代码问题,服务器端是否忘记关闭连接 调整系统参数,一般一个CLOSE-WAIT会维持2小时,可以通过参数来缩短这个时间
高并发场景下,客户端主动关闭连接 和 服务器端主动关闭连接的区别?
客户端主动关闭连接,会造成服务器端大量连接处于 CLOSE-WAIT状态。
服务器端主动关闭连接,会造成服务器端大量连接处于 TIME-WAIT状态。
首先说一下停止-等待协议,我们发送方发送消息给接收方,当接收方接收到消息后会给予确认,我们就可以一个发送一个确认这样子一直发送消息,不过会有异常的情况比如消息丢失或者确认消息丢失,这样子我们就可以引入超时重传的机制保证可靠性。
不过这种协议是串行的交互方式对信道的利用率不高,但是TCP协议利用滑动串口配合累计确认,用过窗口滑动将串行发送改为并行发送,通过累计确认不用对每一个确认号进行确认当一个确认号到达了就表示这个确认号之前的所有的数据正确到达了,可以大幅减少确认号数据减轻双方负担,可以更合理的利用带宽,可以解决刚刚说的停止-等待协议这个问题、
网络拥塞:网络中对资源的需求超过了这个资源所能提供处理能力和容量,网络性能就会变差会出现数据丢失,时延增加等情况。
网络拥塞不是一个单点问题,拥塞控制是全局交的的一个问题。
拥塞控制:就是防止网络中注入过多数据,出现网络负载过大的情况。具体是通过慢开始和拥塞避免、快重传和快恢复实现的。
拥塞窗口:是tcp协议基于窗口的一个变量配置,发送方会维持一个拥塞窗口的状态变量可以动态变化,tcp头部发送方让自己的发送窗口等于拥塞窗口,
门限值:拥塞避免算法启动的阈值,当超过门限值启动慢启动算法
传输轮次:一次报文发送和确认的时间,RTT表示一次传输轮次所用时间
慢开始:由于刚开始发送数据时不知道网络拥塞情况,所以发送端先将拥塞窗口值设为1(这里的1是指一个MSS(最大报文段长度)),然后每次收到一组报文的确认后,就将拥塞窗口加上确认报文数,这样做的结果就是每过一个传输轮次(RTT时间), 理论上可以让拥塞窗口大小乘以二。
拥塞避免:拥塞避免算法就是让发送端拥塞窗口每过一个传输轮次只加一。
当拥塞窗口 > 慢开始门限时,采用拥塞避免算法
当拥塞窗口 < 慢开始门限时,采用慢开始算法
当两者相等时,都可以使用。
无论在慢开始阶段还是拥塞避免阶段,只要网络中出现拥塞(具体判断拥塞的方法是发送方没有按时收到确认),就将慢开始门限设置为当前拥塞窗口值的一半,然后将拥塞窗口值设为1,重新执行慢开始算法。
上面两种算法合称AIMD算法(加法增大乘法减小算法),加法增大是指拥塞避免算法,乘法减小是指 出现拥塞时门限值减半。
有时候虽然报文丢失,但可能没有发生拥塞,就会导致超时重传并误认为发生拥塞然后进入慢开始算法,就会降低传输效率。
然后通过快重传与快恢复改进TCP性能,
快重传:接收方接收到失序报文时,应当立即发送重复的确认,这样当发送方一旦接收到3个重复确认时,就可以提前对丢失的报文进行重传,而不需要等待丢失报文的超时重传也就不会误认为是发生拥塞,提高吞吐量。
快恢复:当发送方一连接收到3个重复确认时,执行快恢复算法,将慢开始门限值和拥塞窗口调整为当前窗口的一半,然后开始拥塞避免算法。这是因为此时网络很可能还没有发生严重的拥塞, 不然也不会一连收到3个重复确认,但重复确认意味着确实有报文丢失,所以只是将窗口值调整为当前窗口的一半。
也有的快恢复实现是将拥塞窗口扩大一点,加上3,因为既然连续收到三个重复确认,就表明有三个数据报文段已经发过去了,
流量控制就是让发送方的发送速率不要那么快,要让接收方来得及接受,如果发送速率太快的话,数据分组可能就会丢失,所以流量控制是TCP协议实现可靠性的一部分。
流量控制是点对点通信量的控制,拥塞控制是网络全局数据量的控制。
流量控制是由滑动窗口协议实现的。具体做法是接收端在ACK报文中包含自己接收窗口的大小,此时发送方发送窗口的大小不能超过接收方接收窗口的数值。
TCP窗口的单位是字节。
为什么会发生粘包?
因为TCP是面向连接的安全的流式传输协议,所以用TCP进行数据传输的时候并不是以数据包的形式推送的,而是流的形式。但是实际开发的时候,数据大多都是以数据包的形式发送的,并且每次数据包的大小可能都不一样。并且每个数据包都有我们自定义的数据格式,接收端基于这个格式进行解析,在进行逻辑处理。但是接收端可能一次性接收到不止一个数据包,也不能以一种固定的格式拆分数据包,所以就会有多个数据包沾黏在一起的现象。
TCP默认使用Nagle算法,只有收到前一个分组的确认后,才能发送下一个分组,等待确认的过程中,发送端缓冲区就可能将多个较小的分组打包在一起发送,就是粘包。
Nagle算法简单的讲就是,等待服务器应答包到达后,在发送下一个数据包。数据在发送端被缓存,如果缓存到达指定大小就将其发送,或者在上一个数据的应答包到达,将缓存区一次性全部发送
发送方发送速率太快,接收方来不及处理时,也会发生粘包。
但是我认为TCP本身就是流式传输协议,黏包问题他是我们的一个特殊需求。
黏包解决方案:
1 使用标准的应用层协议(比如:http、https)来封装要传输的不定长的数据包
2 在每条数据的尾部添加特殊字符,如果遇到特殊字符,代表当条数据接收完毕了
有缺陷:效率低,需要一个字节一个字节接收,接收一个字节判断一次,判断是不是那个特殊字符串
3 在发送数据块之前,在数据块最前边添加一个固定大小的数据头,这时候数据由两部分组成:数据头 + 数据块
数据头:存储当前数据包的总字节数,接收端先接收数据头,然后在根据数据头接收对应大小的字节
数据块:当前数据包的内容
为什么会发生拆包?
1、要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包。
2、待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。
ICMP用于检验网络畅通,以及丢包时返回丢包原因的一个协议。
ICMP的应用:
ping:通过向目的主机发送ICMP请求报文,目的主机返回响应报文,根据成功响应的次数和时间来估算网络质 量。
路由追踪:重复发送数据报,每次逐步增大TTL值(最大允许中转的路由数),可以通过每次数据报的响应消息来 获得到达目的主机经过的路由IP和往返时间
ARP协议的作用: ARP协议将IP地址转换成对应的MAC地址
在TCP/IP模型中属于IP层(网络层),在OSI模型中属于链路层
ARP工作流程 :
当主机要发送IP数据报时,会先从本机的ARP缓存中查询是否有目标主机的MAC地址,若有则将目标 MAC地址写入MAC帧首部,若没有,则要向局域网广播一个ARP请求分组,局域网中的目标主机收到 广播后,会向源主机单播一个带有自己MAC地址的响应分组,主机收到响应分组后,会将目标MAC地 址写入自己的ARP缓存。如果源主机和目标主机不在同一个局域网内,那么源主机ARP缓存中保存的就是目标主机的IP地址和下 一个路由器的MAC地址,所以在传输过程中,目标IP地址一直不变,但是每到一个路由器,目标MAC 地址就会变化
1、用户可以随意改变IP地址,MAC地址是不可修改的
2、当今互联网中存在很多子网,IP地址可以用来划分子网,如果只用MAC地址的话,还需要记录每一 个MAC地址所在的地域 IP地址相当于收货地址,MAC地址相当于收件人
得分点:DNS解析、TCP握手、HTTP缓存、重定向、服务器状态码、渲染引擎和JS引擎互斥、渲染过程、浏览器进程、网络进程、渲染进程
标准回答:
输入地址,浏览器查找域名的 IP 地址。
浏览器向该IP地址的web 服务器发送一个HTTP请求,在发送请求之前浏览器和服务器建立TCP的三次握手,判断是否有HTTP缓存,如果是强制缓存且在有效期内,不再向服务器发请求,如果是HTTP协商缓存则向后端发送请求且和后端服务器对比,在有效期内,服务器返回304,直接从浏览器获取数据,如果不在有效期内服务器返回200,返回新数据。
请求发送出去服务器返回重定向,浏览器再按照重定向的地址重新发送请求。
如果请求的参数有问题,服务器端返回404,如果服务器端挂了返回500。
如果有数据一切正常,当浏览器拿到服务器的数据之后,开始渲染页面同时获取HTML页面中图片、音频、视频、CSS、JS,在这期间获取到JS文件之后,会直接执行JS代码,阻塞浏览器渲染,因为渲染引擎和JS引擎互斥,不能同时工作,所以通常把Script标签放在body标签的底部。
渲染过程就是先将HTML转换成dom树,再将CSS样式转换成stylesheet,根据dom树和stylesheet创建布局树,对布局树进行分层,为每个图层生成绘制列表,再将图层分成图块,紧接着光栅化将图块转换成位图,最后合成绘制生成页面。
加分回答:整个流程中涉及到浏览器的浏览器进程、网络进程和渲染进程:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。