# 网络面试问题

# 七层网络模型与五层模型

network01
  1. 应用层: 网络流程应用(表示的是用户界面,例如Telnet,HTTP)
  2. 表示层: 数据表示 (数据如何呈现,特殊处理例如加密,比如ASCII,JPEG)
  3. 会话层: 主机间的通信(将不同应用程序的数据分开。建立,管理和终止应用之间的会话)
  4. 传输层: 端到端连接(可靠或不可靠的传递,例如TCP,UDP)
  5. 网络层: 地址和最佳路径(提供路由器用于路径的逻辑寻址,比如IP)
  6. 数据链路层: 媒体访问(将位组合成字节,将字节组合成帧,使用MAC地址访问,错误检测-比如HDLC)
  7. 物理层: 二进制传输(在设备之间移动bits。例如V.35)
network02
  1. 应用层: 也是我们能直接接触到的就是应用层,我们电脑或手机使用的应用软件都是在应用层实现。
  2. 传输层: 应用层的数据包会传给传输层,传输层是为应用层提供网络支持的。
  3. 网络层: 负责网数据传输。
  4. 数据链路层: 让数据在⼀个链路中传输,这就是数据链路层,它主要为⽹络层提供链路级别传输的服务。
  5. 物理层: 当数据准备要从设备发送到⽹络时,需要把数据包转换成电信号,让其可以在物理介质中传输,这⼀层就是物理层,它主要是为数据链路层提供⼆进制传输的服

# linux的虚拟网络模型

计算机网络中常用的虚拟网络模型包括了:host模型、bridge模型、NAT模型、overlay network模型。

# HTTP八种请求方法

  1. OPTIONS(options): 返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性。
  2. HEAD(head): 向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以再不必传输整个响应内容的情况下,就可以获取包含在响应小消息头中的元信息。
  3. GET(get): 向特定的资源发出请求。注意: GET方法不应当被用于产生“副作用”的操作中,例如在Web Application中,其中一个原因是GET可能会被网络蜘蛛等随意访问。Loadrunner中对应get请求函数: web_link和web_url
  4. POST(post): 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 Loadrunner中对应POST请求函数: web_submit_data,web_submit_form。
  5. PUT(put): 向指定资源位置上传其最新内容。
  6. DELETE(delete): 请求服务器删除Request-URL所标识的资源。
  7. TRACE(trace): 回显服务器收到的请求,主要用于测试或诊断。
  8. CONNECT(connect): HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

# session和cookie原理

Session Cookie
原理 会话状态保存在服务器端的技术 Cookie是一种在浏览器的技术。Cookie是一种在浏览器的技术。
存储的位置 session 可以存储在Redis中、数据库中、应用程序中 cookie存储在浏览器端
安全性不同 不安全 不安全
容量和个数限制 没有的限制 cookie 有容量限制,每个站点下的 cookie也有个数限制

Session和Cookie的安全性都存在一定的问题。

  • Session的安全性主要取决于Session lD的安全性,如果SessionlD被青测或者被盗取, 攻击者就可以访问用户的Session数据。为了提高Session的安全性,可以采用加密、哈希等方式对Session ID进行保护
  • Cookie的安全性也存在一定的问题, 如果Cookie被窃取,攻击者就可以模拟用户的身份进行访问。为了提高Cookie的安全性,可以采用加密、签名等方式对Cookie进行保护。 此外,还可以设置Cookie的过期时间,避免Cookie长时间存在,增加被攻击的风险。

# Cookie和Session的区别

当通过浏览器进行网页访问的时候,服务器可以把某一些状态数据以key-value的方式,写入到Cookie里面存储到客户端浏览器。 然后客户端下一次再访问服务器的时候,就可以携带这些状态数据发送到服务器端,服务端可以根据Cookie里面携带的内容来识别使用者。

Session表示一个会话,它是属于服务器端的容器对象,默认情况下,针对每一个浏览器的请求。Servlet容器都会分配一个Session。 Session本质上是一个ConcurrentHashMap,可以存储当前会话产生的一些状态数据。Http协议本身是一个无状态协议,也就是服务器并不知道客户端发送过来的多次请求是属于同一个用户。 所以Session是用来弥补Http无状态的不足,简单来说,服务器端可以利用session来存储客户端在同一个会话里面的多次请求记录。

户端第一次访问服务端的时候,服务端会针对这次请求创建一个会话,并生成一个唯一的sessionId来标注这个会话。 然后服务端把这个sessionid写入到客户端浏览器的cookie里面,用来实现客户端状态的保存。 在后续的请求里面,每次都会携带sessionid,服务器端就可以根据这个sessionid来识别当前的会话状态。

img.png

所以,总的来看,Cookie是客户端的存储机制,Session是服务端的存储机制。

# get与post的区别

GET是从服务器上获得数据;POST是向服务器传递数据

  1. url可见性:get参数url可见;posturl参数不可见
  2. 数据传输上:get通过拼接url进行传递参数;post通过body体传输参数
  3. 缓存性:get请求是可以缓存的,post请求不可以缓存
  4. 后退页面的反应:get请求页面后退时,不产生影响,post请求页面后退时,会重新提交请求
  5. 传输数据的大小:get一般传输数据大小不超过2k-4k(根据浏览器不同,限制不一样,但相差不大),post请求传输数据的大小根据php.ini 配置文件设定,也可以无限大。
  6. 安全性:这个也是最不好分析的,原则上post肯定要比get安全,毕竟传输参数时url不可见,但也挡不住部分人闲的没事在那抓包玩。安全性个人觉得是没多大区别的,防君子不防小人就是这个道理。对传递的参数进行加密,其实都一样。
  7. 数据包:GET产生一个TCP数据包;POST产生两个TCP数据包。对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data, 服务器响应200 ok(返回数据)。在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。并不是所有浏览器都会在POST中发送两次包 Firefox就只发送一次。

什么大型网站都采用get方法,而非post方法

  1. get 是从服务器上获取数据,post 是向服务器传送数据。get和post 只是一种传递数据的方式, get 也可以把数据传到服务器,他们的本质都是发送请求和接收结果。只是组织格式和数据量上面有差别。
  2. get是把参数数据队列加到提交表单的 ACTION 属性所指的 URL 中,值和表单内各个字段一一对应,在URL中可以看到。 post 是通过 HTTPpost 机制,将表单内各个字段与其内容放置在HTML HEADER 内一起传送到 ACTION 属性所指的 URL 地址。 用户看不到这个过程。因为get设计成传输小数据,而且最好是不修改服务器的数据,所以浏览器一般都在地址栏里面可以看到, 但post一般都用来传递大数据,或比较隐私的数据,所以在地址栏看不到,能不能看到不是协议规定,是浏览器规定的。
  3. 对于get方式,服务器端用 Request.QueryString获取变量的值,对于post方式,服务器端用 Request.Form 获取提交的数据。 没明白,怎么获得变量和你的服务器有关,和get或post无关,服务器都对这些请求做了封装
  4. get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。 但理论上,IIS4 中最大量为 80KB,IIS5 中为 100KB。post 基本没有限制,我想大家都上传过文件, 都是用 post 方式的。只不过要修改 form 里面的那个 type 参数
  5. get安全性非常低,post 安全性较高。如果没有加密,他们安全级别都是一样的,随便一个监听器都可以把所有的数据监听到,不信你自己下一个监听网络资源的软件

# HTTP三次握手原理

network03

三次握手流程:

  1. 第一次握手: 建立连接时,客户端发送syn包(syn=x)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN: 同步序列编号(Synchronize Sequence Numbers)。
  2. 第二次握手: 服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
  3. 第三次握手: 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

# 为什么是三次握手?不是两次、四次?

  1. 三次握手才可以阻止重复历史连接的初始化(主要原因)
  2. 三次握手才可以同步双方的初始序列号
  3. 三次握⼿才可以避免资源浪费

# 三次握手过程中是否可以携带数据

第三次握手时是可以携带数据的,但第一二次握手时不可以携带数据

  1. 假如第一次握手可以携带数据的话,那么会放大 SYN 洪泛。如果有人要恶意攻击服务器, 每次都在第一次握手中的 SYN 报文中放入大量的数据,然后疯狂重复发送 SYN 报文的话, 就会让服务器开辟大量的缓存来接收这些报文,内存会很容易耗尽,从而拒绝服务。

  2. 第三次握手时客户端已经处于 ESTABLISHED 状态,对于客户端来说,他已经建立起连接了, 并且已经知道服务器的接收和发送能力是正常的,所以也就可以携带数据了。

# 三次握⼿是如何避免重复历史连接的初始化?

⽹络环境是错综复杂的,往往并不是如我们期望的⼀样,先发送的数据包,就先到达⽬标主机,可能会由于⽹络拥堵等乱七⼋糟的原因,会使得旧的数据包,先到达⽬标主机。 客户端连续发送多次 SYN 建⽴连接的报⽂,在网络拥堵情况下:

  • ⼀个旧 SYN 报⽂⽐最新的 SYN 报⽂早到达了服务端;
  • 那么此时服务端就会回⼀个 SYN + ACK 报⽂给客户端;
  • 客户端收到后可以根据⾃身的上下⽂,判断这是⼀个历史连接(序列号过期或超时),那么客户端就会发送 RST 报⽂给服务端,表示中止这⼀次连接。
  • 如果是两次握⼿连接,就不能判断当前连接是否是历史连接,三次握⼿则可以在客户端(发送⽅)准备发送第三次报⽂时,客户端因有⾜够的上下⽂来判断当前连接是否是历史连接:
  • 如果是历史连接(序列号过期或超时),则第三次握⼿发送的报⽂是 RST 报⽂,以此中⽌历史连接;
  • 如果不是历史连接,则第三次发送的报⽂是 ACK 报⽂,通信双⽅就会成功建⽴连接; 所以,TCP使⽤三次握⼿建⽴连接的最主要原因是防⽌历史连接初始化了连接。

# 三次握手才如何同步双方序列号

TCP 协议的通信双⽅, 都必须维护⼀个序列号, 序列号是可靠传输的⼀个关键因素,它的作⽤:

  1. 接收⽅可以去除重复的数据。
  2. 接收⽅可以根据数据包的序列号按序接收。
  3. 可以标识发送出去的数据包中, 哪些是已经被对⽅收到的。

序列号在TCP连接中占据着常重要的作⽤,所以当客户端发送携带初始序列号的 SYN 报⽂的时 候,需要服务端回⼀个 ACK 应答报⽂, 表示客户端的 SYN 报⽂已被服务端成功接收,那当服务端发送初始序 列号给客户端的时候,依然也要得到客户端的应答回应,这样⼀来⼀回, 才能确保双⽅的初始序列号能被可靠的同步。

# 三次握⼿才怎样避免资源浪费?

如果只有两次握⼿,当客户端的 SYN 请求连接在⽹络中阻塞,客户端没有接收到 ACK 报⽂,就会重新发送SYN , 由于没有第三次握⼿,服务器不清楚客户端是否收到了⾃⼰发送的建⽴连接的 ACK 确认信号,所以每收到⼀个 SYN就只能先主动建⽴⼀个连接, 这会造成什么情况呢? 如果客户端的 SYN 阻塞了,重复发送多次 SYN 报⽂,那么服务器在收到请求后就会建⽴多个冗余的无效的连接,造成不必要的资源浪费。

# HTTP四次挥手原理

network04

四次挥手的流程:

  1. 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
  2. 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
  3. 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
  4. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
  5. 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
  6. 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

# 为什么需要四次挥⼿?

TCP是全双工模式,并且支持半关闭特性,提供了连接的一端在结束发送后还能接收来自另一端数据的能力。 任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候, 则发出连接释放通知,对方确认后就完全关闭了TCP连接。

# TIME_WAIT等待的时间是2MSL?

网络中可能存在来⾃发送⽅的数据包,当这些发送⽅的数据包 被接收⽅处理后⼜会向对⽅发送响应,所以⼀来⼀回需要等待2倍的时间。 如果被动关闭⽅没有收到断开连接的最后的ACK 报⽂,就会触发超时重发Fin报⽂,另⼀⽅接收到FIN后,会重发ACK给被动关闭⽅,⼀来⼀去正好2个MSL。

在Linux 系统⾥ 2MSL 默认是 60 秒,那么⼀个 MSL 也就是 30 秒。Linux 系统停留在 TIME_WAIT 的时 间为固定的 60 秒。 其定义在 Linux 内核代码⾥的名称为TCP_TIMEWAIT_LEN:define TCP_TIMEWAIT_LEN (60*HZ), 如果要修改 TIME_WAIT 的时间⻓度,只能修改 Linux 内核代码⾥ TCP_TIMEWAIT_LEN 的值,并重新编译Linux内核 。

# MSL与TTL的区别

MSL 的单位是时间,⽽TTL 是经过路由跳数。

  1. MSL是Maximum Segment Lifetime,报⽂最⼤⽣存时间,它是任何报⽂在网络上存在的最⻓时间,超过这个时间报⽂将被丢弃。
  2. TTL 字段: ⽽IP 头中有⼀个TTL字段,是IP数据报可以经过的最大路由数,每经过⼀个处理他的路由器此值就减 1,当此值为0则数据报将被丢弃,同时发送ICMP 报⽂通知源主机 。

# 为什么需要TIME_WAIT状态?

主动发起关闭连接的⼀⽅,才会有TIME-WAI状态。 需要TIME-WAIT状态,主要是两个原因:

  1. 保证让迟来的TCP报文段有足够的时间被识别和丢弃。连接结束了,网络中的延迟报文也应该被丢弃掉,以免影响立刻建立的新连接。
  2. 可靠终止TCP连接。如果最后一个ACK报文因为网络原因被丢弃,此时server因为没有收到ACK而超时重传FIN报文,处于TIME_WAIT状态的client可以继续对FIN报文做回复,向server发送ACK报文。

# TIME_WAIT过长有什么危害

如果服务器有处于 TIME-WAIT 状态的TCP,则说明是由服务器⽅主动发起的断开请求。 过多的 TIME-WAIT 状态主要的危害有两种:

  1. 第⼀是内存资源占⽤;
  2. 第⼆是对端⼝资源的占⽤,⼀个 TCP 连接⾄少消耗⼀个本地端⼝。

如何优化 TIME_WAIT?

  1. 打开 net.ipv4.tcp_tw_reuse 和 net.ipv4.tcp_timestamps 选项;
    如下的 Linux 内核参数开启后,则可以复⽤处于 TIME_WAIT 的 socket 为新的连接所⽤。 有⼀点需要注意的是,tcp_tw_reuse 功能只能⽤客户端(连接发起⽅),因为开启了该功能,在调⽤ connect() 函数时,内核会随机找⼀个 time_wait 状态超过 1 秒的连接给新的连接复⽤。
  2. net.ipv4.tcp_max_tw_buckets。 这个值默认为 18000,当系统中处于 TIME_WAIT 的连接⼀旦超过这个值时,系统就会将后⾯的 TIME_WAIT 连接 状态重置 。 这个⽅法过于暴⼒,⽽且治标不治本,带来的问题远⽐解决的问题多,不推荐使⽤
  3. 程序中使⽤ SO_LINGER ,应⽤强制使⽤ RST 关闭
    我们可以通过设置 socket 选项,来设置调⽤ close 关闭连接⾏为,我们可以通过设置 socket 选项,来设置调⽤ close 关闭连接⾏为 。

如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP 有⼀个机制是保活机制。这个机制的原理是这样的: 定义⼀个时间段,在这个时间段内,如果没有任何连接相关的活动,TCP 保活机制会开始作⽤, 每隔⼀个时间间 隔,发送⼀个探测报⽂,该探测报文包含的数据⾮常少,如果连续几个探测报⽂都没有得到响应, 则认为当前的 TCP 连接已经死亡,系统内核将错误信息通知给上层应⽤程序 :

在 Linux 内核可以有对应的参数可以设置保活时间、保活探测的次数、保活探测的时间间隔,以下都为默认值: 
tcp_keepalive_time=7200: 
表示保活时间是7200秒(2⼩时),也就2⼩时内如果没有任何连接相关的活动,则会启动保活机制
tcp_keepalive_intvl=75: 
表示每次检测间隔75秒;
tcp_keepalive_probes=9: 
表示检测9次⽆响应,认为对⽅是不可达的,从⽽中断本次的连接。

如果开启了 TCP 保活,需要考虑以下⼏种情况:

  1. 第⼀种,对端程序是正常⼯作的。当 TCP 保活的探测报⽂发送给对端, 对端会正常响应,这样 TCP 保活时间会被 重置,等待下⼀个 TCP 保活时间的到来。
  2. 第⼆种,对端程序崩溃重启。当 TCP 保活的探测报⽂发送给对端后,对端是可以响应的,但由于没有该连接的 有效信息,会产⽣⼀个 RST 报⽂,这样很快就会发现 TCP 连接已经被重置。
  3. 第三种,是对端程序崩溃,或对端由于其他原因导致报⽂不可达。当 TCP 保活的探测报⽂发送给对端后,⽯沉⼤ 海,没有响应,连续⼏次,达到保活探测次数后,TCP 会报告该 TCP 连接已经死亡。

# HTTP状态码有那些

1xx类状态码

属于提示信息,是协议处理中的⼀种中间状态,实际⽤到的⽐较少。

2xx 类状态码

表示服务器成功处理了客户端的请求,也是我们最愿意看到的状态。

  1. 200 OK是最常⻅的成功状态码,表示⼀切正常。如果是⾮ HEAD 请求,服务器返回的响应头都会有 body 数据。
  2. 204 No Content也是常⻅的成功状态码,与200OK基本相同,但响应头没有body 数据。
  3. 206 Partial Content是应⽤于 HTTP 分块下载或断点续传,表示响应返回的body数据并不是资源的全部,⽽是其中的⼀部分,也是服务器处理成功的状态。

3xx 类状态码

表示客户端请求的资源发送了变动,需要客户端⽤新的 URL 新发送请求获取资源,也就是重定向。

  1. 301 Moved Permanently表示永久定向,说明请求的资源已经不存在了,需改⽤新的 URL 再次访问。
  2. 302 Found表示临时定向,说明请求的资源还在,但暂时需要⽤另⼀个 URL 来访问。
  3. 301和30 都会在响应头⾥使⽤字段Location,指明后续要跳转的URL,浏览器会⾃动指定定向新的URL。
  4. 304 Not Modified不具有跳转的含义,表示资源未修改,定向已存在的缓冲⽂件,也称缓存定向,⽤于缓存控制。

4xx 类状态码

表示客户端发送的报⽂有误,服务器⽆法处理,也就是错误码的含义。

  1. 400 Bad Request表示客户端请求的报⽂有错误,但只是个笼统的错误。
  2. 403 Forbidden表示服务器禁⽌访问资源,并不是客户端的请求出错。
  3. 404 Not Found表示请求的资源在服务器上不存在或未找到,所以⽆法提供给客户端。

5xx 类状态码

表示客户端请求报⽂正确,但是服务器处理时内部发⽣了错误,属于服务器端的错误码。

  1. 500 Internal Server Error与400类型,是个笼统通⽤的错误码,服务器发⽣了什么错误,我们并不知道。
  2. 501 Not Implemented表示客户端请求的功能还不⽀持,类似“即将开业,敬请期待”的意思。
  3. 502 Bad Gateway通常是服务器作为⽹关或代理时返回的错误码,表示服务器⾃身⼯作正常,访问后端服务器发⽣了错误。
  4. 503 Service Unavailable表示服务器当前很忙,暂时⽆法响应服务器,类似“⽹络服务正忙,请稍后在试”的意思
  5. 504 GetWay timeout表示网关超时
  6. 505 HTTP version not support表示的HTTP协议不支持。

# HTTP1.0优点

  1. 简单HTTP基本的报⽂格式就是 header + body ,头部信息也是 key-value 简单⽂本的形式,易于理解,降低了学习 和使⽤的⻔槛。
  2. 灵活和易于扩展 HTTP协议⾥的各类请求⽅法、URI/URL、状态码、头字段等每个组成要求都没有被固定死,都允许开发⼈员⾃定 义和扩充。
  3. 应⽤⼴泛和跨平台 互联⽹发展⾄今,HTTP 的应⽤范围⾮常的⼴泛。

# HTTP1.0缺点

HTTP 协议⾥有优缺点⼀体的双刃剑,分别是⽆状态、明⽂传输,同时还有⼀⼤缺点不安全。

  1. ⽆状态的坏处,既然服务器没有记忆能⼒,它在完成有关联性的操作时会⾮常麻烦。
  2. 不安全 HTTP 比较严重的缺点就是不安全:通信使用明文(不加密),内容可能会被窃听。

# HTTP/1.1性能改进

  1. 使⽤TCP⻓连接的⽅式改善了 HTTP/1.0短连接造成的性能开销。
  2. ⽀持管道⽹络传输,只要第⼀个请求发出去了,不必等其回来,就可以发第⼆个请求出去,可以减少整体的响应时间。

# HTTP/1.1性能瓶颈

  1. 请求/响应头部(Header)未经压缩就发送,⾸部信息越多延迟越⼤。只能压缩Body的部分。
  2. 发送冗⻓的⾸部。每次互相发送相同的⾸部造成的浪费较多。
  3. 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端⼀直请求不到数据,也就是队头阻塞; 没有请求优先级控制。
  4. 请求只能从客户端开始,服务器只能被动响应。

# HTTP2.0特性

  1. 采用头部压缩技术,http2.0压缩请求头中重复的部分。
  2. 头信息和数据体采用二进制格式,http1.1采用的纯⽂本形式的报⽂。
  3. 采用多路复用技术,利用连接的socket的数量,同时减少队头阻塞。
  4. 服务器推送技术,服务不再是被动地响应,也可以主动向客户端发 送消息
  5. 数据流技术,指定数据流的优先级。优先级⾼的请求,服务器就先响应该请求。

# keepalive timer的作用

服务器每收到一次客户的数据,就重新设置保活计时器,时间的设置通常是两个小时。若两个小时都没有收到客户端的数据, 服务端就发送一个探测报文段,以后则每隔 75秒钟发送一次。若连续发送10个探测报文段后仍然无客户端的响应, 服务端就认为客户端出了故障,接着就关闭这个连接。

# Http1.0,Http1.1和Http2.0的区别

  1. Http1.0短连接(100张图,100次tcp握手和挥手)
  2. Http1.1长连接(100张图,1次tcp握手挥手)
  3. Http2.0长连接+io多路复用模型(五大模型之一)

# HTTP的优化的方式

  1. 开启HTTP的缓存字段,尽避免发送HTTP重复请求。
  2. 多个小请求合并成⼀个大的请求,减少HTTP请求的次数。
  3. 延迟发送请求,根据按需获取资源减少HTTP请求次数
  4. 采用压缩技术减少 HTTP 响应的数据⼤⼩。

# HTTPS连接传输过程

HTTPS
  1. Client发起一个HTTPS的请求,根据RFC2818的规定,Client知道需要连接Server的443(默认)端口。
  2. Server把事先配置好的公钥证书(public key certificate)返回给客户端。
  3. Client验证公钥证书:比如是否在有效期内,证书的用途是不是匹配Client请求的站点,是不是在CRL吊销列表里面,它的上一级证书是否有效,这是一个递归的过程,直到验证到根证书(操作系统内置的Root证书或者Client内置的Root证书)。如果验证通过则继续,不通过则显示警告信息。
  4. Client使用伪随机数生成器生成加密所使用的对称密钥,然后用证书的公钥加密这个对称密钥,发给Server。
  5. Server使用自己的私钥(private key)解密这个消息,得到对称密钥。至此,Client和Server双方都持有了相同的对称密钥。
  6. Server使用对称密钥加密“明文内容A”,发送给Client。
  7. Client使用对称密钥解密响应的密文,得到“明文内容A”。
  8. Client再次发起HTTPS的请求,使用对称密钥加密请求的“明文内容B”,然后Server使用对称密钥解密密文,得到“明文内容B”。

# HTTP与HTTPS有哪些区别

  1. HTTP 是超⽂本传输协议,信息是明⽂传输,存在安全⻛险的问题。HTTPS则解决HTTP不安全的缺陷,在 TCP 和 HTTP ⽹络层之间加⼊了 SSL/TLS 安全协议,使得报⽂能够加密传输。
  2. HTTP 连接建⽴相对简单,TCP 三次握⼿之后便可进⾏ HTTP 的报⽂传输。⽽ HTTPS 在 TCP 三次握⼿之 后,还需进⾏ SSL/TLS 的握⼿过程,才可进⼊加密报⽂传输。
  3. HTTP 的端⼝号是 80,HTTPS 的端⼝号是 443。
  4. HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的

# HTTPS解决了HTTP的安全问题

  1. 信息加密:交互信息⽆法被窃取,但你的号会因为⾃身忘记账号⽽没。
  2. 校验机制:⽆法篡改通信内容,篡改了就不能正常显示,但百度竞价排名依然可以搜索垃圾⼴告。
  3. 身份证书:证明淘宝是真的淘宝⽹,但你的钱还是会因为剁⼿⽽没。 可⻅,只要⾃身不做恶,SSL/TLS 协议是能保证通信是安全的。

# HTTPS的优化方式

  1. 对于硬件优化的⽅向

因为 HTTPS 是属于计算密集型,应该选择计算⼒更强的 CPU,⽽且最好选择⽀持 AES-NI 特性的 CPU, 这个特性可以在硬件级别优化 AES 对称加密算法,加快应⽤数据的加解密。

  1. 对于软件优化的⽅向

如果可以,把软件升级成较新的版本,⽐如将 Linux 内核 2.X 升级成 4.X,将 openssl 1.0.1 升级到 1.1.1, 因为新版本的软件不仅会提供新的特性,⽽且还会修复⽼版本的问题。

  1. 对于协议优化的⽅

密钥交换算法应该选择 ECDHE 算法,⽽不⽤ RSA 算法,因为 ECDHE 算法具备前向安全性,⽽且客户端可 以在第三次握⼿之后,就发送加密应⽤数据,节省了 1 RTT。 将 TSL1.2 升级 TSL1.3,因为 TSL1.3 的握⼿过程只需要 1 RTT,⽽且安全性更强。

  1. 对于证书优化的⽅向

服务器应该选⽤ ECDSA 证书,⽽⾮ RSA 证书,因为在相同安全级别下,ECC 的密钥⻓度⽐ RSA 短很多, 这样可以提⾼证书传输的效率; 服务器应该开启 OCSP Stapling 功能,由服务器预先获得 OCSP 的响应,并把响应结果缓存起来, 这样 TLS 握⼿的时候就不⽤再访问 CA 服务器,减少了⽹络通信的开销,提⾼了证书验证的效率;

  1. 对于重连HTTPS时

我们可以使⽤⼀些技术让客户端和服务端使⽤上⼀次 HTTPS 连接使⽤的会话密钥,直接恢 复会话,⽽不⽤再重新⾛完整的 TLS 握⼿过程。 常⻅的会话重⽤技术有 Session ID 和 Session Ticket,⽤了会话重⽤技术,当再次重新连 HTTPS 时,只需要 1 RTT 就可以恢复会话。 对于 TLS1.3 使⽤ Pre-shared Key 会话重⽤技术,只需要 0 RTT 就可以恢复会话。这些会话重⽤技术虽然好⽤, 但是存在⼀定的安全⻛险,它们不仅不具备前向安全,⽽且有重放攻击的⻛险,所以 应当对会话密钥设定⼀个合理的过期时间。

# ARQ协议

  1. 自动重传请求ARQ协议:停止等待协议中超时重传是指只要超过一段时间仍然没有收到确认, 就重传前面发送过的分组(认为刚才发送过的分组丢失了)。因此每发送完一个分组需要设置一个超时计时器, 其重传时间应比数据在分组传输的平均往返时间更长一些。这种自动重传方式常称为自动重传请求ARQ。

  2. 连续ARQ协议:连续 ARQ 协议可提高信道利用率。发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去, 而不需要等待对方确认。接收方一般采用累计确认,对按序到达的最后一个分组发送确认, 表明到这个分组为止的所有分组都已经正确收到了。

# ARP协议

即地址解析协议, 用于实现从 IP 地址到 MAC 地址的映射,即询问目标IP对应的MAC地址。

# RARP协议

逆地址解析协议。允许局域网的物理机器从网关服务器的ARP表或缓存上请求IP地址。

# ICMP协议的功能

CMP协议是一种面向无连接的协议,用于传输出错报告控制信息。它是一个非常重要的协议,它对于网络安全具有极其重要的意义。 它属于网络层协议,主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。 当遇到IP数据无法访问目标、IP路由器无法按当前的传输速率转发数据包等情况时,会自动发送ICMP消息。 比如我们日常使用得比较多的ping,就是基于ICMP的。

# QUIC协议原理

# QUIC协议的优点

# HTTP/3的特点

# 重传机制的方式

TCP 实现可靠传输的⽅式之⼀,是通过序列号与确认应答。在TCP中,当发送端的数据到达接收主机时, 接收端主机会返回⼀个确认应答消息,表示已收到消息。但在错综复杂的⽹络,并不⼀定能顺利能正常的数据传输, 万⼀数据在传输过程中丢失了呢? 所以TCP针对数据包丢失的情况,会⽤重传机制解决。

  1. 超时重传

重传机制的其中⼀个⽅式,就是在发送数据时,设定⼀个定时器,当超过指定的时间后, 没有收到对⽅的 ACK 确认应答报⽂,就会重发该数据,也就是我们常说的超时重传。 TCP 会在以下两种情况发⽣超时重传:

  • 数据包丢失
  • 确认应答丢失
  1. 快速重传

TCP 还有另外⼀种快速重传(Fast Retransmit)机制,它不以时间为驱动,⽽是以数据驱动重传。 所以,快速重传的⼯作⽅式是当收到三个相同的ACK 报⽂时,会在定时器过期之前,重传丢失的报⽂段。

  1. SACK重传

TCP 头部选项字段⾥加⼀个 SACK 的东⻄,它可以将缓存的地图发送给发送⽅,这样发送 ⽅就可以知道哪些数据收到了, 哪些数据没收到,知道了这些信息,就可以只重传丢失的数据。

  1. D-SACK重传

Duplicate SACK ⼜称 D-SACK ,其主要使⽤了SACK来告诉发送⽅有哪些数据被重复接收了。

# 滑动窗口原理

TCP 利用滑动窗口实现流量控制的机制。滑动窗口(Sliding window)是一种流量控制技术。早期的网络通信中, 通信双方不会考虑网络的拥挤情况直接发送数据。由于大家不知道网络拥塞状况,同时发送数据,导致中间节点阻塞掉包, 谁也发不了数据,所以就有了滑动窗口机制来解决此问题。

TCP 中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据。 发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。当滑动窗口为0时,发送方一般不能再发送数据报,

但有两种情况除外:

  1. 一种情况是可以发送紧急数据,例如,允许用户终止在远端机上的运行进程。
  2. 另一种情况是发送方可以发送一个 1 字节的数据报来通知接收方重新声明它希望接收的下一字节及发送方的滑动窗口大小。

# 拥塞控制

在⽹络出现拥堵时,如果继续发送⼤量数据包,可能会导致数据包时延、丢失等,这时TCP就会重传数据,但是 ⼀重传就会导致⽹络的负担更重, 于是会导致更⼤的延迟以及更多的丢包,这个情况就会进⼊恶性循环被不断地放⼤,所以,TCP不能忽略⽹络上发⽣的事, 它被设计成⼀个⽆私的协议,当⽹络发送拥塞时,TCP会⾃我牺牲,降低发送的数据量。于是,就有了拥塞控制, 控制的⽬的就是避免发送⽅的数据填满整个⽹络。为了在发送⽅调节所要发送数据的量,定义了⼀个叫做拥塞窗⼝的概念。

拥塞窗口:cwnd是发送⽅维护的⼀个的状态变量,它会根据⽹络的拥塞程度动态变化的。 发送窗⼝swnd和接收窗⼝rwnd是约等于的关系,那么由于加⼊了拥塞窗⼝的概念后, 此时发送窗⼝的值是swnd=min(cwnd, rwnd),也就是拥塞窗⼝和接收窗⼝中的最⼩值。 拥塞窗⼝cwnd变化的规则:

  1. 只要⽹络中没有出现拥塞,cwnd就会增⼤;
  2. 但⽹络中出现了拥塞,cwnd就减少;

怎么判断出现了拥塞呢 其实只要发送⽅没有在规定时间内接收到ACK应答报⽂,也就是发⽣了超时重传,就会认为⽹络出现了拥塞。

# 拥塞控制算法

  1. 慢启动
    • 有⼀个叫慢启动⻔限ssthresh(slow start threshold)状态变量。当 cwnd < ssthresh 时,使⽤慢启动算法。
  2. 拥塞避免
    • 当 cwnd >= ssthresh 时,就会使⽤拥塞避免算法。它的规则是:每当收到⼀个 ACK 时,cwnd增加1/cwnd
  3. 拥塞发⽣
    • 当⽹络出现拥塞,也就是会发⽣数据包重传,重传机制主要有两种:超时重传、快速重传
  4. 快速恢复
    • 快速重传和快速恢复算法⼀般同时使⽤,快速恢复算法是认为,你还能收到 3 个重复ACK 说明⽹络也不那么糟 糕,所以没有必要像 RTO 超时那么强烈。

# TCP和UDP区别:

  1. 连接 TCP是⾯向连接的传输层协议,传输数据前先要建⽴连接。 UDP 是不需要连接,即刻传输数据。
  2. 服务对象 TCP 是⼀对⼀的两点服务,即⼀条连接只有两个端点。 UDP ⽀持⼀对⼀、⼀对多、多对多的交互通信
  3. 可靠性 TCP 是可靠交付数据的,数据可以⽆差错、不丢失、不重复、按需到达。 UDP 是尽最⼤努⼒交付,不保证可靠交付数据。
  4. 拥塞控制、流量控制 TCP 有拥塞控制和流ᰁ控制机制,保证数据传输的安全性。 UDP 则没有,即使⽹络⾮常拥堵了,也不会影响 UDP 的发送速率。
  5. ⾸部开销 TCP ⾸部⻓度较⻓,会有⼀定的开销,⾸部在没有使⽤选项字段时是 20 个字节,如果使⽤了选项字段则会变⻓的。 UDP ⾸部只有 8 个字节,并且是固定不变的,开销较⼩。
  6. 传输⽅式 TCP 是流式传输,没有边界,但保证顺序和可靠。 UDP 是⼀个包⼀个包的发送,是有边界的,但可能会丢包和乱序。
  7. 分⽚不同 TCP 的数据⼤⼩如果⼤于MSS⼤⼩,则会在传输层进⾏分⽚,⽬标主机收到后,也同样在传输层组装 TCP 数据包, 如果中途丢失了⼀个分⽚,只需要传输丢失的这个分⽚。 UDP 的数据⼤⼩如果⼤于 MTU ⼤⼩,则会在 IP 层进⾏分⽚, ⽬标主机收到后,在 IP 层组装完数据,接着 再传给传输层,但是如果中途丢了⼀个分⽚,在实现可靠传输的 UDP 时则就需要重传所有的数据包, 这样 传输效率⾮常差,所以通常 UDP 的报⽂应该⼩于 MTU。

# TCP和UDP应⽤场景

  1. 由于TCP是⾯向连接,能保证数据的可靠性交付,因此经常⽤于: FTP⽂件传输 HTTP/HTTPS
  2. 由于UDP⾯向⽆连接,它可以随时发送数据,再加上UDP本身的处理既简单⼜⾼效,因此经常⽤于:包总量较少的通信,如DNS、SNMP等视频、⾳频等多媒体通信⼴播通信 。

# TCP 协议如何保证可靠传输?

  1. 应用数据被分割成 TCP 认为最适合发送的数据块。
  2. TCP给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
  3. 校验和:TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
  4. TCP的接收端会丢弃重复的数据。
  5. 流量控制:TCP连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
  6. 拥塞控制:当网络拥塞时,减少数据的发送。
  7. ARQ协议:也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
  8. 超时重传:当 TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。

# 什么是SYN洪泛

SYN 洪泛是指利用 TCP 需要三次握手的特性,攻击者伪造 SYN 报文向服务器发起连接,服务器在收到报文后用 ACK 应答, 但之后攻击者不再对该响应进行应答,造成一个半连接。假设攻击者发送大量这样的报文,那么被攻击主机就会造成大量的半连接, 耗尽其资源,导致正常的 SYN 请求因为队列满而被丢弃,使得正常用户无法访问。

# 半连接队列与全连接队列

半连接队列: 服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接, 服务器会把这种状态下的请求连接放在一个队列里,我们把这种队列称之为半连接队列。 全连接队列:完成三次握手后建立起的连接就会放在全连接队列中。

# 什么是网络风暴

网络风暴是指由于网络上过多的广播数据帧,几乎占满了网络整个带宽而导致网络速度极慢的一种故障。 一个数据帧或包被传输到本地网段 (由广播域定义)上的每个节点就是广播;由于网络拓扑的设计和连接问题, 或其他原因导致广播在网段内大量复制,传播数据帧,导致网络性能下降,甚至网络瘫痪。这就是广播风暴。

广播风暴现象是最常见的数据洪泛之一,是一种典型的雪球效应。当广播风暴产生时,它们将在网络中无休止的传播. 甚至可以在网络中无限制的不停的繁殖。过多的广播包消耗了大量的网络带宽.占用了大量的网络资源. 导致正常的数据包无法正常在网络中传送.这时,网络设备处理器高负荷运转。不仅网络设备会受到影响。 而且所有的主机都要接收链路层的广播数据包,因而受到危害每秒数万级的数据包通常都会使网卡工作异常繁忙. 超出了处理器的负荷.设备操作系统反映迟缓,网络通讯严重受阻.严重地危害了网络的正常运行, 大大降低了整个以太网的通信性能.甚至会造成网络的整体瘫痪。

# 网络风暴的原因

网络设备误用:我们平时使用的交换机具有地址记忆的功能.在通信时,是点对点转发信息的,通常不会产生广播风暴。但有时我们由于种种原因,误将集线器当成交换机来使用。

网卡损坏或则交换机端口损坏:如果网络机器的网卡损坏或则交换机端口损坏。也同样会产生广播风暴。损坏的网卡,不停向交换机发送大量的数据包,产生了大量无用的数据包,产生了广播风暴。在实际工作中,同一局域网中,开始有几台计算机速度较慢,最后却可能导致整个局域网网速都很慢。究其原因是与其相连的交换机端口故障造成的当交换机有一个端El传输速率非常缓慢,最后导致整台交换机都慢下来,通常是因为连接该计算机的网卡损坏.导致不断的发送广播包造成,也有可能是因为交换机端口故障,广播包阻塞不能及时发出。

网络环路:只所以会产生网络环路。一般是由于一条物理网络线路的两端,同时接在了一台网络设备中。对于一些复杂的网络线路设计。应该有一个清晰的网络拓扑结构,切不可凭空想象,以免造成网络环路,影响了整个网络的运行环境。

网络病毒:一种现象是该网卡的发送包和接收包的数量在快速增加,则说明该计算机感染了蠕虫病毒。目前,一些比较流行的网络蠕虫病毒如震荡波、RPC等病毒。一旦有机器中毒后,会立即通过网络进行传播另一种现象是当计算机不断出现IP地址冲突的提示,是由于局域网中有计算机感染了病毒,并采用了TP地址欺骗和MAC地址欺骗的方法不断的向局域网发送广播造成的网络病毒的传播,将会损耗大量的网络带宽,占用网络资源,引起网络堵塞,造成网络广播风暴。

黑客软件的使用:目前,一些上网者,经常利用网络执法官、网络剪刀手等黑客软件,对网络进行攻击,由于这些软件的使用。网络也可能会引起广播风暴。

网络视频:部分网络视频传输设备为了便于网络视频点播,通常采用UDP的方式。以广播数据包的形式对外进行发送。如果在专用网络中也使用这种方式,很容易引发广播风暴,导致网络阻塞,因此必须通过相关设置来杜绝这类故障。

恶劣环境:如不合适的温度、湿度、震动和电磁干扰等因素,尤其是电磁干扰比较严重的环境下,同样也有可能会使网络变得不稳定,造成网络数据传输错误,引发广播风暴。

# 粘包,拆包原理

TCP是面向流,没有界限的一串数据。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分, 拆包:一个完整的包可能会被TCP拆分成多个包进行发送,粘包:多个小的包封装成一个大的数据包发送,

TCP的粘包和拆包为什么会产生粘包和拆包

  1. 要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包;
  2. 接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包;
  3. 要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包;
  4. 待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。即TCP报文长度-TCP头部长度>MSS。

解决方案

  1. 在数据尾部增加一个特殊字符进行分割,例如FTP协议;
  2. 将数据大小设置为固定的,如果数据长度不够,则使用空位补全;
  3. 将数据分为两部分,消息头和消息体;其中消息头大小固定,且包含一个字段声明内容体的大小。

# 浏览器中的URL的全部流程

  1. DNS 解析:将域名解析成对应的 IP 地址。
  2. TCP连接:与服务器通过三次握手,建立 TCP 连接。
  3. 向服务器发送 HTTP 请求。
  4. 服务器处理请求,返回HTTp响应。
  5. 浏览器解析并渲染页面。
  6. 断开连接:TCP 四次挥手,连接结束。

# 网站打不开,怎么排查问题?

  1. 先确定是服务端问题还是客户端问题。
  2. 先确认浏览器是否可以访问其他网站:
    • 如果不可以那就说明客户端网络自身有问题,那就需要检查客户端的网络配置(WiFi是否正常,网络接口是否正常)。
    • 如果可以,那就说明客户端是没有问题。
  3. 抓包确认DNS是否能解析IP地址:
    • 如果不能解析出来IP地址,则说明域名写错了。
    • 如果可以解析出来IP地址,那就抓包确认服务是否连接
  4. 抓包确认三次连接服务:
    • 如果能够建立三次握手服务。并且发出了HTTP请求,但是页面还是没有显示,那就查询返回的状态码。
    • 404:检查输入的URL是否正确、500:服务器有问题、200:表示请求是成功,那就查询前端渲染是否正常。
  5. 如果客户端网路正常,但是访问速度很慢,导致没有显示出来
    • 那就查询客户端流量是否太大,导致TCP发生了丢包的问题。

# 域名解析的⼯作流程

DNS
  1. 客户端⾸先会发出⼀个 DNS 请求,问 www.server.com 的 IP 是啥,并发给本地 DNS 服务器(也就是客户端 的 TCP/IP 设置中填写的 DNS 服务器地址)。
  2. 本地域名服务器收到客户端的请求后,如果缓存⾥的表格能找到 www.server.com,则它直接返回 IP 地址。 如果没有,本地 DNS 会去问它的根域名服务器:“⽼⼤, 能告诉我 www.server.com 的 IP 地址吗?” 根域名 服务器是最⾼层次的,它不直接⽤于域名解析,但能指明⼀条道路。
  3. 根 DNS 收到来⾃本地 DNS 的请求后,发现后置是 .com,说:“www.server.com 这个域名归 .com 区域管 理”,我给你 .com 顶级域名服务器地址给你,你去问问它吧。”
  4. 本地 DNS 收到顶级域名服务器的地址后,发起请求问“⽼⼆, 你能告诉我 www.server.com 的 IP 地址吗?”
  5. 顶级域名服务器说:“我给你负责 www.server.com 区域的权威 DNS 服务器的地址,你去问它应该能问到”。
  6. 本地 DNS 于是转向问权威 DNS 服务器:“⽼三,www.server.com对应的IP是啥呀?” server.com 的权威 DNS 服务器,它是域名解析结果的原出处。为啥叫权威呢?就是我的域名我做主。
  7. 权威 DNS 服务器查询后将对应的 IP 地址 X.X.X.X 告诉本地 DNS。
  8. 本地 DNS 再将 IP 地址返回客户端,客户端和⽬标建⽴连接。

# 长连接与短连接

  • 长连接:多用于操作频繁,点对点的通讯,而且连接数不能太多情况。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,再次操作时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接,如果用短连接频繁的通信会造成socket 错误,而且频繁的socket创建造成资源的浪费。
  • 短链接:**WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,**而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,所以并发量大,但每个用户无需频繁操作情况下需用短连好。

# 长轮询与短轮询

  • 短轮询:重复发送Http请求,查询目标事件是否完成,优点:编写简单,缺点:浪费带宽和服务器资源。
  • 长轮询:在服务端hold住Http请求(死循环或者sleep等等方式),等到目标时间发生,返回Http响应。优点:在无消息的情况下不会频繁的请求,缺点:编写复杂。我们日常是的一种的长连接的是使用但是有一个超时机制。超过一定时候就会默认断开。

# CSRF攻击

一般来说,攻击者通过伪造用户的浏览器的请求,向访问一个用户自己曾经认证访问过的网站发送出去,使目标网站接收并误以为是用户的真实操作而去执行命令。常用于盗取账号﹑转账、发送虚假消息等。攻击者利用网站对请求的验证漏洞而实现这样的攻击行为,网站能够确认请求来源于用户的浏览器,却不能验证请求是否源于用户的真实意愿下的操作行为。 防范手段:

  1. 验证HTTP Referer字段:HTTP头中的Referer字段记录了该HTTP请求的来源地址。在通常情况下,访问一个安全受限页面的请求来自于同一个网站,而如果黑客要对其实施CSRF攻击,他一般只能在他自己的网站构造请求。因此,可以通过验证Referer值来防御CSRF攻击。
  2. 关键操作页面加上验证码,后台收到请求后通过判断验证码可以防御CSRF。但这种方法对用户不太友好。
  3. 在请求地址中添加token并验证:CSRF攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于cookie中,因此黑客可以在不知道这些验证信息的情况下直接利用用户自己的cookie 来通过安全验证。要抵御CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。可以在TTP请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个token,如果请求中没有token或者token内容不正确,则认为可能是CSRF攻击而拒绝该请求。 种方式相比于验证HTTP Referer字段安全一些。
  4. 在HTTP头中自定义属性并验证:这种方法也是使用token并进行验证,和上一种方法不同的是,这里并不是把token以参数的形式置于HTTP请求之中,而是把它放到HTTP头中自定义的属性里。通过XMLHttpRequest这个类,可以一次性给所有该类请求加上csrftoken这个 HTTP头属性,并把 token值放入其中。这样解决了上种方法在请求中加入 token的不便,同时,通过 XMLHttpRequest请求的地址不会被记录到浏览器的地址栏,也不用担心token会透过 Referer泄露到其他网站中去。

# CC攻击与DDOS攻击

  • CC攻击:主要是用来攻击页面的,模拟多个用户不停的对你的页面进行访问,从而使你的系统资源消耗殆尽。
  • DDOS攻击:分布式拒绝服务攻击,指借助服务器技术将多个计算机联合起来作为攻击平台,来对一个或多个目标发动DDOS攻击。

# 服务端挂了,客户端的TCP连接还在吗?

当客户端向一个已经断开的服务端发送消息时,底层TCP协议会尝试发送数据包,但是由于服务端已经不再响应,数据包将无法到达服务端。 TCP协议会尝试多次发送数据包,一般来说,TCP协议的最大重传次数是6次。如果在达到重传次数以后仍然没有收到确认消息,TCP协议会认为连接已经失效并关闭连接。 由于正常情况下,TCP连接的关闭需要四次挥手,但是服务器是下线状态导致无法完成FIN数据包的发送。这个时候客户端会尝试多次重传FIN数据包,但最终会因为没有收到服务端的响应而放弃发送FIN数据包,并直接关闭连接。 这个时候客户端直接关闭连接是安全的。

# HTTP协议和RPC协议的区别

功能特性

  • http是一个属于应用层的超文本传输协议,是万维网数据通信的基础,主要服务在网页端和服务端的数据传输上。
  • RPC是一个远程过程调用协议,它的定位是实现不同计算机应用之间的数据通信,屏蔽通信底层的复杂性,让开发者就像调用本地服务一样完成远程服务的调用。

因此,这两个协议在定位层面就完全不同。

从实现原理

  • http协议是一个已经实现并且成熟的应用层协议,它定义了通信的报文格式Request Body和Request Header,以及Response Body和Response Header。也就是说,符合这样一个协议特征的通信协议,才是http协议。
  • RPC只是一种协议的规范,它并没有具体实现,只有按照RPC通信协议规范实现的通信框架,也就是RPC框架,才是协议的具体实现,比如Dubbo、gRPC等。因此,我们可以在实现RPC框架的时候,自定义报文通信的协议规范、自定义序列化方式、自定义网络通信协议的类型等等

因此,从这个层面来说,http是成熟的应用协议,而RPC只是定义了不同服务之间的通信规范。

应用层面

http协议和实现了RPC协议的框架都能够实现跨网络节点的服务之间通信。并且他们底层都是使用TCP协议作为通信基础。 但是,由于RPC只是一种标准协议,只要符合RPC协议的框架都属于RPC框架。因此,RPC的网络通信层也可以使用HTTP协议来实现,比如gRPC、OpenFeign底层都采用了http协议。

# TCP要设计三次握手,我认为有三个方面的原因:

  1. TCP是可靠性通信协议,所以TCP协议的通信双方都必须要维护一个序列号,去标记已经发送出去的数据包,哪些是已经被对方签收的。而三次握手就是通信双方相互告知序列号的起始值,为了确保这个序列号被收到,所以双方都需要有一个确认的操作。
  2. TCP协议需要在一个不可靠的网络环境下实现可靠的数据传输,意味着通信双方必须要通过某种手段来实现一个可靠的数据传输通道,而三次通信是建立这样一个通道的最小值。当然还可以四次、五次,只是没必要浪费这个资源。
  3. 防止历史的重复连接初始化造成的混乱问题,比如说在网络比较差的情况下,客户端连续多次发送建立连接的请求,假设只有两次握手,那么服务端只能选择接受或者拒绝这个连接请求,但是服务端不知道这次请求是不是之前因为网络堵塞而过期的请求,也就是说服务端不知道当前客户端的连接是有效还是无效。

# 网络四元组

四元组,简单理解就是在TCP协议中,去确定一个客户端连接的组成要素,它包括源IP地址、目标IP地址、源端口号、目标端口号。

正常情况下,我们对于网络通信的认识可能是这样

img.png

服务端通过ServerSocket建立一个对指定端口号的监听,比如8080。 客户端通过目标ip和端口就可以和服务端建立一个连接,然后进行数据传输。 但是我们知道的是,一个Server端可以接收多个客户端的连接,比如像这种情况:

img.png

那,当多个客户端连接到服务端的时候,服务端需要去识别每一个连接。并且TCP是全双工协议,也就是说数据允许在连接的两个方向上同时传输,因此这里的客户端,如果是反向通信,它又变成了服务端。

img.png

所以基于这两个原因,就引入了四元组的设计,也就是说,当一个客户端和服务端建立一个TCP连接的时候,通过源IP地址、目标IP地址、源端口号、目标端口号来确定一个唯一的TCP连接。因为服务器的IP和端口是不变的,只要客户端的IP和端口彼此不同就OK了。

img.png

同一个客户端主机上有三个连接连到Server端,那么这个时候源IP相同,源端口号不同。此时建立的四元组就是(10.23.15.3,59461 , 192.168.8.135,8080)其中,源端口号是每次建立连接的时候系统自动分配的。

# select poll epoll原理

img.png

img.png

时间复杂度:O(n), fd_set(监听的端口个数):32位机默认是1024个,64位机默认是2048。

缺点:

  1. 单进程可以打开fd有限制;
  2. 对socket进行扫描时是线性扫描,即采用轮询的方法,效率较低,需要应用程序中数据的拷贝到内核中,这样来进行查找判断时候有对应的套接字;
  3. 用户空间和内核空间的复制非常消耗资源;

poll原理同步多路IO复用类似

  1. 调用过程和select类似。
  2. 时间复杂度:O(n)
  3. 其和select不同的地方:采用链表的方式替换原有fd_set数据结构,而使其没有连接数的限制

epoll原理: 应用程序与内核共享一块数据内存,这样不用将数据复制到内核中进行查找。利用的事件驱动的方式进行,代理轮训的方式进行遍历,效率更加高。 epoll利用数据结构:红黑树和链表两种数据结构构建。

img.png

时间复杂度:O(1)

epoll的工作方式:epoll的两种工作方式:1.水平触发(LT)2.边缘触发(ET)。

  1. LT模式:若就绪的事件一次没有处理完要做的事件,就会一直去处理。即就会将没有处理完的事件继续放回到就绪队列之中(即那个内核中的链表),一直进行处理。
  2. ET模式:就绪的事件只能处理一次,若没有处理完会在下次的其它事件就绪时再进行处理。而若以后再也没有就绪的事件,那么剩余的那部分数据也会随之而丢失。

# TCP粘包和拆包与解决方案

粘包问题:如果一次请求发送的数据量比较小,没达到缓冲区大小,TCP则会将多个请求合并为同一个请求进行发送,这就形成了粘包问题。 拆包问题:如果一次请求发送的数据量比较大,超过了缓冲区大小,TCP就会将其拆分为多次发送,这就是拆包。

img.png

粘包和拆包的常见解决方案有以下4种:

  1. 发送端将每个包都封装成固定的长度,比如100字节大小。如果不足100字节可通过补0或空等进行填充到指定长度;
  2. 发送端在每个包的末尾使用固定的分隔符,例如\r\n。 如果发生拆包需等待多个包发送过来之后再找到其中的\r\n进行合并;例如,FTP协议;
  3. 将消息分为头部和消息体,头部中保存整个消息的长度,只有读取到足够长度的消息之后才算是读到了一个完整的消息;
  4. 通过自定义协议进行粘包和拆包的处理。

为什么UDP没有粘包?

粘包拆包问题在数据链路层、网络层以及传输层都有可能发生。日常的网络应用开发大都在传输层进行,由于UDP有消息保护边界,不会发生粘包拆包问题,因此粘包拆包问题只发生在TCP协议中。