开通VIP,畅享免费电子书等14项超值服
首页
好书
留言交流
下载APP
联系客服
2022.08.26山东
大家好,这次给大家带来了计算机网络六十二问,三万字,七十图详解,大概是全网最全的网络面试题。
建议大家收藏了慢慢看!
计算机网络体系结构,一般有三种:OSI七层模型、TCP/IP四层模型、五层结构。
简单说,OSI是一个理论上的网络通信模型,TCP/IP是实际上的网络通信模型,五层结构就是为了介绍网络原理而折中的网络通信模型。
OSI七层模型
OSI七层模型是国际标准化组织(InternationalOrganizationforStandardization)制定的一个用于计算机或通信系统间互联的标准体系。
TCP/IP四层模型
应用层:对应于OSI参考模型的(应用层、表示层、会话层)。
传输层:对应OSI的传输层,为应用层实体提供端到端的通信功能,保证了数据包的顺序传送及数据的完整性。
网际层:对应于OSI参考模型的网络层,主要解决主机到主机的通信问题。
网络接口层:与OSI参考模型的数据链路层、物理层对应。
五层体系结构
传输层:对应OSI参考模型的的传输层
网络层:对应OSI参考模型的的网络层
数据链路层:对应OSI参考模型的的数据链路层
物理层:对应OSI参考模型的的物理层。
一张表格总结常见网络协议:
对于发送方而言,从上层到下层层层包装,对于接收方而言,从下层到上层,层层解开包装。
这个过程类似写信,写一封信,每到一层,就加一个信封,写一些地址的信息。到了目的地之后,又一层层解封,传向下一个目的地。
这道题,大概的过程比较简单,但是有很多点可以细挖:DNS解析、TCP三次握手、HTTP报文格式、TCP四次挥手等等。
我们以输入www.baidu.com为例:
各个过程都使用了哪些协议?
DNS,英文全称是domainnamesystem,域名解析系统,它的作用也很明确,就是域名和IP相互映射。
DNS的解析过程如下图:
假设你要查询www.baidu.com的IP地址:
具体来说,Socket是一套标准,它完成了对TCP/IP的高度封装,屏蔽网络细节,以方便开发者更好地进行网络编程。
HTTP状态码首先应该知道个大概的分类:
几个常用的,面试之外,也应该记住:
之前写过一篇:程序员五一被拉去相亲,结果彻底搞懂了HTTP常用状态码,还比较有意思,可以看看。
说一下301和302的区别?
用一个比喻,301就是嫁人的新垣结衣,302就是有男朋友的长泽雅美。
其中,POST、DELETE、PUT、GET的含义分别对应我们最熟悉的增、删、改、查。
可以从以下几个方面来说明GET和POST的区别:
HTTP中的GET方法是通过URL传递数据的,但是URL本身其实并没有对数据的长度进行限制,真正限制GET长度的是浏览器。
例如IE浏览器对URL的最大限制是2000多个字符,大概2kb左右,像Chrome、Firefox等浏览器支持的URL字符数更多,其中FireFox中URL的最大长度限制是65536个字符,Chrome则是8182个字符。
这个长度限制也不是针对数据部分,而是针对整个URL。
HTTP协议定义了浏览器怎么向服务器请求文档,以及服务器怎么把文档传给浏览器。
在浏览器和服务器之间的请求和响应的交互,必须按照规定的格式和遵循一定的规则,这些格式和规则就是超文本传输协议HTTP。
PS:这道题和上面浏览器输入网址发生了什么那道题大差不差。
HTTP报文有两种,HTTP请求报文和HTTP响应报文:
HTTP请求报文
HTTP请求报文的格式如下:
HTTP请求报文的第一行叫做请求行,后面的行叫做首部行,首部行后还可以跟一个实体主体。请求首部之后有一个空行,这个空行不能省略,它用来划分首部与实体。
请求行包含三个字段:
HTTP响应报文
HTTP响应报文的格式如下:
HTTP/1.0200OKContent-Type:text/plainContent-Length:137582Expires:Thu,05Dec199716:00:00GMTLast-Modified:Wed,5August199615:55:28GMTServer:Apache0.84
HelloWorldHTTP响应报文的第一行叫做状态行,后面的行是首部行,最后是实体主体。URI,统一资源标识符(UniformResourceIdentifier,URI),标识的是Web上每一种可用的资源,如HTML文档、图像、视频片段、程序等都是由一个URI进行标识的。
URL,统一资源定位符(UniformResourceLocation),它是URI的一种子集,主要作用是提供资源的路径。
它们的主要区别在于,URL除了提供了资源的标识,还提供了资源访问的方式。这么比喻,URI像是身份证,可以唯一标识一个人,而URL更像一个住址,可以通过URL找到这个人——人类住址协议://地球/中国/北京市/海淀区/xx职业技术学院/14号宿舍楼/525号寝/张三.男。
关键需要记住HTTP/1.0默认是短连接,可以强制开启,HTTP/1.1默认长连接,HTTP/2.0采用多路复用。
HTTP/1.0
HTTP/1.1
引入了持久连接,即TCP连接默认不关闭,可以被多个请求复用。
分块传输编码,即服务端每产生一块数据,就发送一块,用”流模式”取代”缓存模式”。
管道机制,即在同一个TCP连接里面,客户端可以同时发送多个请求。
HTTP/2.0
HTTP/3主要有两大变化,传输层基于UDP、使用QUIC保证UDP可靠性。
HTTP/2存在的一些问题,比如重传等等,都是由于TCP本身的特性导致的,所以HTTP/3在QUIC的基础上进行发展而来,QUIC(QuickUDPConnections)直译为快速UDP网络连接,底层使用UDP进行数据传输。
HTTP/3主要有这些特点:
我们拿一张图看一下HTTP协议的变迁:
什么是HTTP的长连接?
TCP长连接可以复用一个TCP连接,来发起多次的HTTP请求,这样就可以减少资源消耗,比如一次请求HTML,如果是短连接的话,可能还需要请求后续的JS/CSS。
如何设置长连接?
通过在头部(请求和响应头)设置Connection字段指定为keep-alive,HTTP/1.0协议支持,但是是默认关闭的,从HTTP/1.1以后,连接默认都是长连接。
在什么时候会超时呢?
TCP的keep-alive包含三个参数,支持在系统内核的net.ipv4里面设置;当TCP连接之后,闲置了tcp_keepalive_time,则会发生侦测包,如果没有收到对方的ACK,那么会每隔tcp_keepalive_intvl再发一次,直到发送了tcp_keepalive_probes,就会丢弃该连接。
HTTP是超本传输协议,信息是明传输,存在安全险的问题。HTTPS则解决HTTP不安全的缺陷,在TCP和HTTP络层之间加了SSL/TLS安全协议,使得报能够加密传输。
HTTP连接建相对简单,TCP三次握之后便可进HTTP的报传输。HTTPS在TCP三次握之后,还需进SSL/TLS的握过程,才可进加密报传输。
HTTP的端号是80,HTTPS的端号是443。
HTTPS协议需要向CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。
因为HTTP是明传输,存在安全上的风险:
窃听险,如通信链路上可以获取通信内容,用户账号被盗。
篡改险,如强制植垃圾告,视觉污染。
冒充险,如冒充淘宝站,用户金钱损失。
所以引入了HTTPS,HTTPS在HTTP与TCP层之间加了SSL/TLS协议,可以很好的解决了这些风险:
信息加密:交互信息法被窃取。
校验机制:法篡改通信内容,篡改了就不能正常显示。
身份证书:能证明淘宝是真淘宝。
所以SSL/TLS协议是能保证通信是安全的。
这道题有几个要点:公私钥、数字证书、加密、对称加密、非对称加密。
HTTPS主要工作流程:
这里还画了一张更详尽的图:
首先,服务端的证书从哪来的呢?
为了让服务端的公钥被家信任,服务端的证书都是由CA(CertificateAuthority,证书认证机构)签名的,CA就是络世界的公安局、公证中,具有极的可信度,所以由它来给各个公钥签名,信任的签发的证书,那必然证书也是被信任的。
CA签发证书的过程,如上图左边部分:
然后CA会使的私钥将该Hash值加密,成CertificateSignature,也就是CA对证书做了签名;
最后将CertificateSignature添加在件证书上,形成数字证书;
客户端校验服务端的数字证书的过程,如上图右边部分:
假如在HTTPS的通信过程中,中间人篡改了证书原文,由于他没有CA机构的私钥,所以CA公钥解密的内容就不一致。
这个无状态的的状态值的是什么?是客户端的状态,所以字面意思,就是HTTP协议中服务端不会保存客户端的任何信息。
比如当浏览器第一次发送请求给服务器时,服务器响应了;如果同个浏览器发起第二次请求给服务器时,它还是会响应,但是呢,服务器不知道你就是刚才的那个浏览器。
那有什么办法记录状态呢?
主要有两个办法,Session和Cookie。
先来看看什么是Session和Cookie:
Session和Cookie到底有什么不同呢?
存储位置不一样,Cookie保存在客户端,Session保存在服务器端。
存储数据类型不一样,Cookie只能保存ASCII,Session可以存任意数据类型,一般情况下我们可以在Session中保持一些常用变量信息,比如说UserId等。
存储大小不同,单个Cookie保存的数据不能超过4K,Session可存储数据远高于Cookie。
Session和Cookie有什么关联呢?
可以使用Cookie记录Session的标识。
分布式环境下Session怎么处理呢?
分布式环境下,客户端请求经过负载均衡,可能会分配到不同的服务器上,假如一个用户的请求两次没有落到同一台服务器上,那么在新的服务器上就没有记录用户状态的Session。
这时候怎么办呢?
可以使用Redis等分布式缓存来存储Session,在多台服务器之间共享。
客户端无法使用Cookie怎么办?
有可能客户端无法使用Cookie,比如浏览器禁用Cookie,或者客户端是安卓、IOS等等。
这时候怎么办?SessionID怎么存?怎么传给服务端呢?
首先是SessionID的存储,可以使用客户端的本地存储,比如浏览器的sessionStorage。
接下来怎么传呢?
PS:TCP三次握手是最重要的知识点,一定要熟悉到问到即送分。
TCP提供面向连接的服务,在传送数据前必须建立连接,TCP连接是通过三次握手建立的。
三次握手的过程:
TCP三次握手通俗比喻:
老张和老王是邻居,这天老张下地了,结果家里有事,热心的邻居老王赶紧跑到村口,开始叫唤老王。
老王:老张唉!我是老王,你能听到吗?
老张一听,是老王的声音:老王老王,我是老张,我能听到,你能听到吗?
老王一听,嗯,没错,是老张:老张,我听到了,我有事要跟你说。
'你老婆要生了,赶紧回家吧!'
老张风风火火地赶回家,老婆顺利地生了个带把的大胖小子。握手的故事充满了幸福和美满。
为什么不能是两次?
由于网络传输是有延时的(要通过网络光纤和各种中间代理服务器),在传输的过程中,比如客户端发起了SYN=1的第一次握手。
如果服务器端就直接创建了这个连接并返回包含SYN、ACK和Seq等内容的数据包给客户端,这个数据包因为网络传输的原因丢失了,丢失之后客户端就一直没有接收到服务器返回的数据包。
如果没有第三次握手告诉服务器端客户端收的到服务器端传输的数据的话,服务器端是不知道客户端有没有接收到服务器端返回的信息的。
服务端就认为这个连接是可用的,端口就一直开着,等到客户端因超时重新发出请求时,服务器就会重新开启一个端口连接。这样一来,就会有很多无效的连接端口白白地开着,导致资源的浪费。
还有一种情况是已经失效的客户端发出的请求信息,由于某种原因传输到了服务器端,服务器端以为是客户端发出的有效请求,接收后产生错误。
所以我们需要“第三次握手”来确认这个过程:
通过第三次握手的数据告诉服务端,客户端有没有收到服务器“第二次握手”时传过去的数据,以及这个连接的序号是不是有效的。若发送的这个数据是“收到且没有问题”的信息,接收后服务器就正常建立TCP连接,否则建立TCP连接失败,服务器关闭连接端口。由此减少服务器开销和接收到失效请求发生的错误。
为什么不是四次?
第一次握手服务端未收到SYN报文
第二次握手客户端未收到服务端响应的ACK报文
客户端会继续重传,直到次数限制;而服务端此时会阻塞在accept()处,等待客户端发送ACK报文
第三次握手服务端为收到客户端发送过来的ACK报文
服务端同样会采用类似客户端的超时重传机制,如果重试次数超过限制,则accept()调用返回-1,服务端建立连接失败;而此时客户端认为自己已经建立连接成功,因此开始向服务端发送数据,但是服务端的accept()系统调用已经返回,此时不在监听状态,因此服务端接收到客户端发送来的数据时会发送RST报文给客户端,消除客户端单方面建立连接的状态。
ACK是为了告诉客户端传来的数据已经接收无误。
而传回SYN是为了告诉客户端,服务端响应的确实是客户端发送的报文。
第3次握手是可以携带数据的。
此时客户端已经处于ESTABLISHED状态。对于客户端来说,它已经建立连接成功,并且确认服务端的接收和发送能力是正常的。
什么是半连接队列?
TCP进入三次握手前,服务端会从CLOSED状态变为LISTEN状态,同时在内部创建了两个队列:半连接队列(SYN队列)和全连接队列(ACCEPT队列)。
顾名思义,半连接队列存放的是三次握手未完成的连接,全连接队列存放的是完成三次握手的连接。
什么是SYNFlood?
那有什么应对方案呢?
主要有syncookie和SYNProxy防火墙等。
syncookie:在收到SYN包后,服务器根据一定的方法,以数据包的源地址、端口等信息为参数计算出一个cookie值作为自己的SYNACK包的序列号,回复SYN+ACK后,服务器并不立即分配资源进行处理,等收到发送方的ACK包后,重新根据数据包的源地址、端口计算该包中的确认序列号是否正确,如果正确则建立连接,否则丢弃该包。
SYNProxy防火墙:服务器防火墙会对收到的每一个SYN报文进行代理和回应,并保持半连接。等发送方将ACK包返回后,再重新构造SYN包发到服务器,建立真正的TCP连接。
PS:问完三次握手,常常也会顺道问问四次挥手,所以也是必须掌握知识点。
TCP四次挥手过程:
数据传输结束之后,通信双方都可以主动发起断开连接请求,这里假定客户端发起
客户端发送释放连接报文,第一次挥手(FIN=1,seq=u),发送完毕后,客户端进入FIN_WAIT_1状态。
服务端发送确认报文,第二次挥手(ACK=1,ack=u+1,seq=v),发送完毕后,服务器端进入CLOSE_WAIT状态,客户端接收到这个确认包之后,进入FIN_WAIT_2状态。
服务端发送释放连接报文,第三次挥手(FIN=1,ACK1,seq=w,ack=u+1),发送完毕后,服务器端进入LAST_ACK状态,等待来自客户端的最后一个ACK。
大白话说四次挥手:
沙雕博主小心翼翼地装起了自己的青轴机械键盘。
挥手的故事总充满了悲伤和遗憾!
再来回顾下四次挥手双方发FIN包的过程,就能理解为什么需要四次了。
从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的ACK和FIN一般都会分开发送,从而比三次握手导致多了一次。
为什么需要等待?
如如果被动关闭没有收到断开连接的最后的ACK报,就会触发超时重发Fin报,另接收到FIN后,会重发ACK给被动关闭,来去正好2个MSL。
设想这样的场景:客户已主动与服务器建立了TCP连接。但后来客户端的主机突然发生故障。显然,服务器以后就不能再收到客户端发来的数据。因此,应当有措施使服务器不要再白白等待下去。这就需要使用保活计时器了。
CLOSE-WAIT状态有什么意义?
服务端收到客户端关闭连接的请求并确认之后,就会进入CLOSE-WAIT状态。此时服务端可能还有一些数据没有传输完成,因此不能立即关闭连接,而CLOSE-WAIT状态就是为了保证服务端在关闭连接之前将待发送的数据处理完。
TIME-WAIT有什么意义?
TIME-WAIT状态发生在第四次挥手,当客户端向服务端发送ACK确认报文后进入TIME-WAIT状态。
它存在的意义主要是两个:
防旧连接的数据包
如果客户端收到服务端的FIN报文之后立即关闭连接,但是此时服务端对应的端口并没有关闭,如果客户端在相同端口建立新的连接,可能会导致新连接收到旧连接残留的数据包,导致不可预料的异常发生。
保证连接正确关闭
假设客户端最后一次发送的ACK包在传输的时候丢失了,由于TCP协议的超时重传机制,服务端将重发FIN报文,如果客户端没有维持TIME-WAIT状态而直接关闭的话,当收到服务端重新发送的FIN包时,客户端就会使用RST包来响应服务端,导致服务端以为有错误发生,然而实际关闭连接过程是正常的。
TIME_WAIT状态过多会导致什么问题
如果服务器有处于TIME-WAIT状态的TCP,则说明是由服务器主动发起的断开请求。
过多的TIME-WAIT状态主要的危害有两种:
第是内存资源占;
第是对端资源的占,个TCP连接少消耗个本地端;
怎么解决TIME_WAIT状态过多?
看一下TCP报文首部的格式:
16位端口号:源端口号,主机该报文段是来自哪里;目标端口号,要传给哪个上层协议或应用程序
32位序号:一次TCP通信(从TCP连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号。
32位确认号:用作对另一方发送的tcp报文段的响应。其值是收到的TCP报文段的序号值加1。
4位首部长度:表示tcp头部有多少个32bit字(4字节)。因为4位最大能标识15,所以TCP头部最长是60字节。
6位标志位:URG(紧急指针是否有效),ACk(表示确认号是否有效),PST(缓冲区尚未填满),RST(表示要求对方重新建立连接),SYN(建立连接消息标志接),FIN(表示告知对方本端要关闭连接了)
16位窗口大小:是TCP流量控制的一个手段。这里说的窗口,指的是接收通告窗口。它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。
16位校验和:由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。注意,这个校验不仅包括TCP头部,也包括数据部分。这也是TCP可靠传输的一个重要保障。
16位紧急指针:一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。因此,确切地说,这个字段是紧急指针相对当前序号的偏移,不妨称之为紧急偏移。TCP的紧急指针是发送端向接收端发送紧急数据的方法。
TCP主要提供了检验和、序列号/确认应答、超时重传、最大消息长度、滑动窗口控制等方法实现了可靠性传输。
连接管理:TCP使用三次握手和四次挥手保证可靠地建立连接和释放连接,这里就不用多说了。
校验和:TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果接收端的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。
TCP提供了一种机制,可以让发送端根据接收端的实际接收能力控制发送的数据量,这就是流量控制。
TCP通过滑动窗口来控制流量,我们看下简要流程:
TCP发送一个数据,如果需要收到确认应答,才会发送下一个数据。这样的话就会有个缺点:效率会比较低。
为了解决这个问题,TCP引入了窗口,它是操作系统开辟的一个缓存空间。窗口大小值表示无需等待确认应答,而可以继续发送数据的最大值。
TCP头部有个字段叫win,也即那个16位的窗口大小,它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度,从而达到流量控制的目的。
“通俗点讲,就是接受方每次收到数据包,在发送确认报文的时候,同时告诉发送方,自己的缓存区还有多少空余空间,缓冲区的空余空间,我们就称之为接受窗口大小。这就是win。”
TCP滑动窗口分为两种:发送窗口和接收窗口。发送端的滑动窗口包含四大部分,如下:
深蓝色框里就是发送窗口。
SND.WND:表示发送窗口的大小,上图虚线框的格子数是10个,即发送窗口大小是10。
SND.NXT:下一个发送的位置,它指向未发送但可以发送的第一个字节的序列号。
SND.UNA:一个绝对指针,它指向的是已发送但未确认的第一个字节的序列号。
接收方的滑动窗口包含三大部分,如下:
Nagle算法和延迟确认是干什么的?
当我们TCP报的承载的数据常的时候,例如个字节,那么整个络的效率是很低的,因为每个TCP报中都会有20个字节的TCP头部,也会有20个字节的IP头部,数据只有个字节,所以在整个报中有效数据占有的比例就会常低。
这就好像快递员开着货送个包裹样浪费。
那么就出现了常的两种策略,来减少报的传输,分别是:
Nagle算法
Nagle算法:任意时刻,最多只能有一个未被确认的小段。所谓“小段”,指的是小于MSS尺寸的数据块,所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到。
Nagle算法的策略:
只要没满上条件中的条,发送直在囤积数据,直到满上的发送条件。
延迟确认
事实上当没有携带数据的ACK,它的络效率也是很低的,因为它也有40个字节的IP头和TCP头,但却没有携带数据报。
为了解决ACK传输效率低问题,所以就衍出了TCP延迟确认。
TCP延迟确认的策略:
当有响应数据要发送时,ACK会随着响应数据起刻发送给对
如果在延迟等待发送ACK期间,对的第个数据报到达了,这时就会刻发送ACK
一般情况下,Nagle算法和延迟确认不能一起使用,Nagle算法意味着延迟发,延迟确认意味着延迟接收,两个凑在一起就会造成更大的延迟,会产生性能问题。
什么是拥塞控制?不是有了流量控制吗?
前的流量控制是避免发送的数据填满接收的缓存,但是并不知道整个络之中发了什么。
般来说,计算机络都处在个共享的环境。因此也有可能会因为其他主机之间的通信使得络拥堵。
在络出现拥堵时,如果继续发送量数据包,可能会导致数据包时延、丢失等,这时TCP就会重传数据,但是重传就会导致络的负担更重,于是会导致更的延迟以及更多的丢包,这个情况就会进恶性循环被不断地放....
所以,TCP不能忽略整个网络中发的事,它被设计成个私的协议,当络发送拥塞时,TCP会我牺牲,降低发送的数据流。
于是,就有了拥塞控制,控制的的就是避免发送的数据填满整个络。
就像是一个水管,不能让太多的水(数据流)流入水管,如果超过水管的承受能力,水管会被撑爆(丢包)。
发送方维护一个拥塞窗口cwnd(congestionwindow)的变量,调节所要发送数据的量。
什么是拥塞窗?和发送窗有什么关系呢?
拥塞窗cwnd是发送维护的个的状态变量,它会根据络的拥塞程度动态变化的。
发送窗swnd和接收窗rwnd是约等于的关系,那么由于加了拥塞窗的概念后,此时发送窗的值是swnd=min(cwnd,rwnd),也就是拥塞窗和接收窗中的最值。
拥塞窗cwnd变化的规则:
拥塞控制有哪些常用算法?
拥塞控制主要有这几种常用算法:
慢启动
拥塞避免
拥塞发生
快速恢复
慢启动算法,慢慢启动。
它表示TCP建立连接完成后,一开始不要发送大量的数据,而是先探测一下网络的拥塞程度。由小到大逐渐增加拥塞窗口的大小,如果没有出现丢包,每收到一个ACK,就将拥塞窗口cwnd大小就加1(单位是MSS)。每轮次发送窗口增加一倍,呈指数增长,如果出现丢包,拥塞窗口就减半,进入拥塞避免阶段。
举个例子:
发包的个数是指数性的增。
为了防止cwnd增长过大引起网络拥塞,还需设置一个慢启动阀值ssthresh(slowstartthreshold)状态变量。当cwnd到达该阀值后,就好像水管被关小了水龙头一样,减少拥塞状态。即当cwnd>ssthresh时,进入了拥塞避免算法。
一般来说,慢启动阀值ssthresh是65535字节,cwnd到达慢启动阀值后
每收到一个ACK时,cwnd=cwnd+1/cwnd
当每过一个RTT时,cwnd=cwnd+1
显然这是一个线性上升的算法,避免过快导致网络拥塞问题。
接着上面慢启动的例子,假定ssthresh为8::
当网络拥塞发生丢包时,会有两种情况:
RTO超时重传
快速重传
如果是发生了RTO超时重传,就会使用拥塞发生算法
这种方式就像是飙车的时候急刹车,还飞速倒车,这。。。
其实还有更好的处理方式,就是快速重传。发送方收到3个连续重复的ACK时,就会快速地重传,不必等待RTO超时再重传。
发快速重传的拥塞发算法:
拥塞窗口大小cwnd=cwnd/2
慢启动阀值ssthresh=cwnd
进入快速恢复算法
快速重传和快速恢复算法一般同时使用。快速恢复算法认为,还有3个重复ACK收到,说明网络也没那么糟糕,所以没有必要像RTO超时那么强烈。
正如前面所说,进入快速恢复之前,cwnd和sshthresh已被更新:
-sshthresh=cwnd
然后,进快速恢复算法如下:
重传包括超时重传、快速重传、带选择确认的重传(SACK)、重复SACK四种。
如果RTO设置很大,等了很久都没重发,这样肯定就不行。
如果RTO设置很小,那很可能数据都没有丢失,就开始重发了,这会导致网络阻塞,从而恶性循环,导致更多的超时出现。
一般来说,RTO略微大于RTT,效果是最佳的。
其实,RTO有个标准方法的计算公式,也叫Jacobson/Karels算法。
SRTT=(1-α)*SRTT+α*RTT//求SRTT的加权平均其次,计算RTTVAR(round-triptimevariation)RTTVAR=(1-β)*RTTVAR+β*(|RTT-SRTT|)//计算SRTT与真实值的差距最后,得出最终的RTORTO=μ*SRTT+*RTTVAR=SRTT+4·RTTVAR在Linux下,α=0.125,β=0.25,μ=1,=4。别问这些参数是怎么来的,它们是大量实践,调出的最优参数。
超时重传不是十分完美的重传方案,它有这些缺点:
在上图,发送发出了1,2,3,4,5份数据:
第份Seq1先送到了,于是就Ack回2;
结果Seq2因为某些原因没收到,Seq3到达了,于是还是Ack回2;
后的Seq4和Seq5都到了,但还是Ack回2,因为Seq2还是没有收到;
发送端收到了三个Ack=2的确认,知道了Seq2还没有收到,就会在定时器过期之前,重传丢失的Seq2。
最后,收到了Seq2,此时因为Seq3,Seq4,Seq5都收到了,于是Ack回6。
如对于上的例,是重传Seq2呢?还是重传Seq2、Seq3、Seq4、Seq5呢?因为发送端并不清楚这连续的三个Ack2是谁传回来的。
根据TCP不同的实现,以上两种情况都是有可能的。可,这是把双刃剑。
为了解决不知道该重传哪些TCP报,于是就有SACK法。
为了解决应该重传多少个包的问题TCP提供了带选择确认的重传(即SACK,SelectiveAcknowledgment)。
SACK机制就是,在快速重传的基础上,接收方返回最近收到报文段的序列号范围,这样发送方就知道接收方哪些数据包是没收到的。这样就很清楚应该重传哪些数据包。
如上图中,发送收到了三次同样的ACK确认报,于是就会触发快速重发机制,通过SACK信息发现只有200~299这段数据丢失,则重发时,就只选择了这个TCP段进重发。
D-SACK,英文是DuplicateSACK,是在SACK的基础上做了一些扩展,主要用来告诉发送方,有哪些数据包,自己重复接受了。
DSACK的目的是帮助发送方判断,是否发生了包失序、ACK丢失、包重复或伪重传。让TCP可以更好的做网络流控。
例如ACK丢包导致的数据包重复:
3499)
TCP的粘包和拆包更多的是业务上的概念!
什么是TCP粘包和拆包?
TCP是面向流,没有界限的一串数据。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。
为什么会产生粘包和拆包呢
要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包;
接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包;
要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包;
待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。即TCP报文长度-TCP头部长度>MSS。
那怎么解决呢?
UDP问的不多,基本上是被拿来和TCP比较。
最根本区别:TCP是面向连接,而UDP是无连接。
说说TCP和UDP的应用场景?
PS:这是多年前的老题了,拉出来怀怀旧。
UDP在传输数据之前不需要先建立连接,远地主机的运输层在接收到UDP报文后,不需要确认,提供不可靠交付。总结就以下四点:
更准确地说,DNS既使用TCP又使用UDP。
当进行区域传送(主域名服务器向辅助域名服务器传送变化的那部分数据)时会使用TCP,因为数据同步传送的数据量比一个请求和应答的数据量要多,而TCP允许的报文长度更长,因此为了保证数据的正确性,会使用基于可靠连接的TCP。
当客户端想DNS服务器查询域名(域名解析)的时候,一般返回的内容不会超过UDP报文的最大长度,即512字节,用UDP传输时,不需要创建连接,从而大大提高了响应速度,但这要求域名解析服务器和域名服务器都必须自己处理超时和重传从而保证可靠性。
IP协议是什么?
IP协议(InternetProtocol)又被称为互联网协议,是支持网间互联的数据包协议,工作在网际层,主要目的就是为了提高网络的可扩展性。
通过网际协议IP,可以把参与互联的,性能各异的网络看作一个统一的网络。
和传输层TCP相比,IP协议是一种无连接/不可靠、尽力而为的数据包传输服务,和TCP协议一起构成了TCP/IP协议的核心。
IP协议有哪些作用?
IP协议主要有以下几个作用:
传输层协议和网络层协议有什么区别?
网络层协议负责提供主机间的逻辑通信;传输层协议负责提供进程间的逻辑通信。
一个IP地址在这鞥个互联网范围内是惟一的,一般可以这么认为,IP地址={<网络号>,<主机号>}。
网络号:它标志主机所连接的网络地址表示属于互联网的哪一个网络。
主机号:它标志主机地址表示其属于该网络中的哪一台主机。
IP地址分为A,B,C,D,E五大类:
A类地址(1~126):以0开头,网络号占前8位,主机号占后面24位。
B类地址(128~191):以10开头,网络号占前16位,主机号占后面16位。
C类地址(192~223):以110开头,网络号占前24位,主机号占后面8位。
D类地址(224~239):以1110开头,保留为多播地址。
E类地址(240~255):以1111开头,保留位为将来使用
假如你有多个不用的绰号,你的朋友可以用其中任何一个绰号叫你,但你的身份证号码却是惟一的。但同时你的绰号也可能和别人重复,假如你不在,有人叫你的绰号,其它人可能就答应了。
一个域名可以对应多个IP,但这种情况DNS做负载均衡的,在用户访问过程中,一个域名只能对应一个IP。
而一个IP却可以对应多个域名,是一对多的关系。
我们知道,IP地址有32位,可以标记2的32次方个地址,听起来很多,但是全球的网络设备数量已经远远超过这个数字,所以IPV4地址已经不够用了,那怎么解决呢?
ARP协议,AddressResolutionProtocol,地址解析协议,它是用于实现IP地址到MAC地址的映射。
首先,每台主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址的对应关系。
当源主机需要将一个数据包要发送到目的主机时,会首先检查自己的ARP列表,是否存在该IP地址对应的MAC地址;如果有﹐就直接将数据包发送到这个MAC地址;如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。此ARP请求的数据包里,包括源主机的IP地址、硬件地址、以及目的主机的IP地址。
网络中所有的主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致。如果不相同,就会忽略此数据包;如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个ARP响应数据包,告诉对方自己是它需要查找的MAC地址。
源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息开始数据的传输。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。
MAC地址和IP地址都有什么作用?
为什么有了MAC地址还需要IP地址?
如果我们只使用MAC地址进行寻址的话,我们需要路由器记住每个MAC地址属于哪个子网,不然一次路由器收到数据包都要满世界寻找目的MAC地址。而我们知道MAC地址的长度为48位,也就是最多共有2的48次方个MAC地址,这就意味着每个路由器需要256T的内存,显然是不现实的。
为什么有了IP地址还需要MAC地址?
只有当设备连入网络时,才能根据他进入了哪个子网来为其分配IP地址,在设备还没有IP地址的时候,或者在分配IP的过程中。我们需要MAC地址来区分不同的设备。
IP地址可以比作为地址,MAC地址为收件人,在一次通信过程中,两者是缺一不可的。
ICMP(InternetControlMessageProtocol),网际控制报文协议。
ICMP协议是一种面向无连接的协议,用于传输出错报告控制信息。
它是一个非常重要的协议,它对于网络安全具有极其重要的意义。它属于网络层协议,主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。
当遇到IP数据无法访问目标、IP路由器无法按当前的传输速率转发数据包等情况时,会自动发送ICMP消息。
比如我们日常使用得比较多的ping,就是基于ICMP的。
ping,PacketInternetGroper,是一种因特网包探索器,用于测试网络连接量的程序。Ping是工作在TCP/IP网络体系结构中应用层的一个服务命令,主要是向特定的目的主机发送ICMP(InternetControlMessageProtocol因特网报文控制协议)请求报文,测试目的站是否可达及了解其有关状态。
一般来说,ping可以用来检测网络通不通。它是基于ICMP协议工作的。假设机器Aping机器B,工作过程如下:
网络安全攻击主要分为两种类型,被动攻击和主动攻击:
DNS劫持即域名劫持,是通过将原域名对应的IP地址进行替换,从而使用户访问到错误的网站,或者使用户无法正常访问网站的一种攻击方式。
域名劫持往往只能在特定的网络范围内进行,范围外的DNS服务器能够返回正常的IP地址。攻击者可以冒充原域名所属机构,通过电子邮件的方式修改组织机构的域名注册信息,或者将域名转让给其它主持,并将新的域名信息保存在所指定的DNS服务器中,从而使用户无法对原域名来进行解析以访问目标地址。
DNS劫持的步骤是什么样的?
怎么应对DNS劫持?
什么是CSRF攻击?
CSRF是如何攻击的呢?
来看一个例子:
用户登陆银行,没有退出,浏览器包含了用户在银行的身份认证信息。
攻击者将伪造的转账请求,包含在在帖子
用户在银行网站保持登陆的情况下,浏览帖子
将伪造的转账请求连同身份认证信息,发送到银行网站
银行网站看到身份认证信息,以为就是用户的合法操作,最后造成用户资金损失。
怎么应对CSRF攻击呢?
检查Referer字段
添加校验token
以在HTTP请求中以参数的形式加入一个随机产生的token,并在服务器端建立一个拦截器来验证这个token,如果请求中没有token或者token内容不正确,则认为可能是CSRF攻击而拒绝该请求。
敏感操作多重校验
DOS:(DenialofService),翻译过来就是拒绝服务,一切能引起拒绝行为的攻击都被称为DOS攻击。最常见的DoS攻击就有计算机网络宽带攻击、连通性攻击。
DDoS:(DistributedDenialofService),翻译过来是分布式拒绝服务。是指处于不同位置的多个攻击者同时向一个或几个目标发动攻击,或者一个攻击者控制了位于不同位置的多台机器,并利用这些机器对受害者同时实施攻击。
主要形式有流量攻击和资源耗尽攻击,常见的DDoS攻击有:SYNFlood、PingofDeath、ACKFlood、UDPFlood等。
DRDoS:(DistributedReflectionDenialofService),中文是分布式反射拒绝服务,该方式靠的是发送大量带有被害者IP地址的数据包给攻击主机,然后攻击主机对IP地址源做出大量回应,从而形成拒绝服务攻击。
如何防范DDoS
针对DDoS中的流量攻击,最直接的方法是增加带宽,理论上只要带宽大于攻击流量就可以了,但是这种方法成本非常高。在有充足带宽的前提下,我们应该尽量提升路由器、网卡、交换机等硬件设施的配置。
针对资源耗尽攻击,我们可以升级主机服务器硬件,在网络带宽得到保证的前提下,使得服务器能够有效对抗海量的SYN攻击包。我们也可以安装专业的抗DDoS防火墙,从而对抗SYNFlood等流量型攻击。瓷碗,负载均衡,CDN等技术都能有效对抗DDos攻击。
XSS攻击也是比较常见,XSS,叫跨站脚本攻击(Cross-SiteScripting),因为会与层叠样式表(CascadingStyleSheets,CSS)的缩写混淆,因此有人将跨站脚本攻击缩写为XSS。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览网页的时候,嵌入其中Web里面的html代码会被执行,从而达到恶意攻击用户的特殊目的。
XSS攻击一般分三种类型:存储型、反射型、DOM型XSS
XSS是如何攻击的呢?
简单说,XSS的攻击方式就是想办法“教唆”用户的浏览器去执行一些这个网页中原本不存在的前端代码。
拿反射型举个例子吧,流程图如下:
如何应对XSS攻击?
对称加密:指加密和解密使用同一密钥,优点是运算速度较快,缺点是如何安全将密钥传输给另一方。常见的对称加密算法有:DES、AES等。
非对称加密:指的是加密和解密使用不同的密钥(即公钥和私钥)。公钥与私钥是成对存在的,如果用公钥对数据进行加密,只有对应的私钥才能解密。常见的非对称加密算法有RSA。
RSA
采用非对称加密的方式,采用公钥进行加密,私钥解密的形式。其私钥长度一般较长,由于需要大数的乘幂求模等运算,其运算速度较慢,不合适大量数据文件加密。
AES
采用对称加密的方式,其秘钥长度最长只有256个比特,加密和解密速度较快,易于硬件实现。由于是对称加密,通信双方在进行数据传输前需要获知加密密钥。