网络分层模型
OSI分层
应用层:为应用程序提供交互服务,通过调用应用层的不同协议实体,从而调用传输层服务来进行网络传输
- HTTP/HTTPS、DNS、Telnet(远程登录服务协议)
- SMTP、POP3、FTP、TFTP(简单文件传输协议)
表示层:主要负责数据格式的转换,如加密解密、转换翻译、压缩解压缩等
会话层:负责建立、维持和终止会话,如服务器验证用户登录便是由会话层完成的
传输层:为主机进程提供端到端的数据传输
- TCP:提供面向连接的、可靠的数据传输服务
- UDP:提供无连接的、尽最大努力的数据传输服务,但不保证数据传输的可靠性
网络层:将传输层的报文段封装成IP分组,选择合适的路由转发
- IP:定义了数据传输的基本单元和格式,以及数据报的递交方法和路由选择
- ICMP:错误侦测与回报机制,能够检测网路的连线状况,是ping和traceroute的工作协议
- IGMP:用于实现组播、广播等通信
数据链路层:将网络层的IP数据报组装成帧,在相邻节点的链路上传送
- ARP、RARP:IP和MAC地址转换
- PPP:通过拨号方式为点对点链路上直接相连的两个结点之间提供数据传输
物理层:实现相邻节点间比特流的透明传输,尽可能屏蔽传输介质和通信手段的差异
TCP/IP分层
- 网络接口层:负责将数据报发送到网络介质上,以及从网络上接收数据报,相当于OSI的物理层和数据层
- 网际层:将传输层的报文段封装成IP分组,选择合适的路由转发
- 传输层:为主机进程提供端到端的数据传输服务
- 应用层:为应用程序提供交互服务,通过调用应用层的不同协议实体,从而调用传输层服务来进行网络传输
输入URL回车
URL解析
判断输入的是一个URL 还是一个待搜索的关键词,若URL不完整则进行补全(前后缀)
然后检查本地缓存是否缓存了该请求资源,如果有则直接将该资源返回给浏览器显示
DNS解析
先查找缓存,没有再使用DNS服务器解析,查找顺序为:
浏览器缓存–>本机缓存–>路由器缓存–>本地DNS服务器缓存若都没有缓存,本地DNS服务器会先查询根域名服务器,若不存在则继续查询顶级域名服务器、权限域名服务器,以此类推。最后本地域名服务器得到IP地址并缓存,返回给主机。
建立TCP连接
这时我们已知IP地址以及默认的端口号了,一般会先尝试建立HTTP连接,经过三次握手建立TCP连接后:
使用HTTP协议
浏览器发送请求到服务器,如果使用的是HTTP协议,则直接返回结果
使用HTTPS协议
若不是HTTP协议,服务器返回3开头的重定向消息,告诉浏览器用的是HTTPS,即IP不用变,但端口号要从80变成443了
完成四次挥手后重建TCP连接,沟通好双方使用的加密传输和身份认证算法,在此过程中也会检验对方的CA安全证书,采用SSL的加密技术来保证传输数据的安全性
浏览器发送HTTP/HTTPS请求
服务器处理请求并返回响应,包括所要访问的网址的一些数据
浏览器将界面进行渲染,还会发送GET请求以获取网页上的其他元素,最后呈现出完整网页
断开TCP连接,四次挥手
Linux 接收网络包的流程
- 网卡接收网络包后会通过DMA技术写入Ring Buffer环形缓冲区,接着通过中断告诉 OS 网络包已到达
- 内核线程从Ring Buffer中获取一个数据帧 sk_buff ,再依次交付给网络接口层、网络层、传输层处理
- 在传输层根据四元组「源 IP、源端口、目的 IP、目的端口」作为标识,找出对应的 Socket,并把数据放到 Socket接收缓冲区
- 应用层程序调用 Socket 接口,将内核的 Socket 缓冲区数据拷贝到应用层缓冲区,然后唤醒用户进程
Linux 发送网络包的流程
- 应用程序调用 Socket 发送数据包的接口,陷入到内核态中的 Socket 层,内核会申请一个内核态的 sk_buff 内存,将用户待发送的数据拷贝到 sk_buff 内存,并将其加入到Socket发送缓冲区
- 网络协议栈从 Socket 发送缓冲区中取出 sk_buff,并按照 TCP/IP 协议栈从上到下逐层处理,最后放到网卡发送队列中
- 传输层填充TCP头
- 网络层选取路由、填充IP头、分片处理
- 网络接口层获取下一跳MAC地址、填充帧头帧尾
- 通过软中断通知网卡驱动程序,将发送队列的中sk_buff 挂到 RingBuffer 中,接着将 sk_buff 数据映射到网卡可访问的内存 DMA 区域,最后触发真实的发送
OSI和TCP/IP的区别
- OSI精确定义了服务、协议和接口,符合面向对象程序设计思想,而TCP/IP没有明确区分。
- OSI没有偏向任何特定的协议,通用性良好,但容易不知道将哪些功能放到哪一层。TCP/IP模型实际上是对已有协议的描述,因此不会出现协议不能匹配的模式。
- TCP/IP考虑了异构网的互联问题,而OSI只考虑用一种标准的公用数据网将各种不同系统互连。
- OSI在网络层支持无连接和面向连接的通信,但在传输层仅有面向连接通信。而TCP/IP则相反,在网际层仅有无连接服务,在传输层支持无连接和面向连接两种模式。
TCP
TCP的三次握手

三次握手过程
- 第一次握手:客户端请求建立连接,向服务端发送一个同步报文(SYN=1),同时选择一个随机数
seq=x作为初始序列号,并进入 SYN_SENT 状态,等待服务器确认。 - 第二次握手:服务端收到连接请求报文后,向客户端发送同步确认报文(SYN=1,ACK=1),确认号为
ack=x+1,同时选择一个随机数seq = y作为初始序列号,此时服务器进入 SYN_RECV 状态。 - 第三次握手:客户端收到服务端的确认后,向服务端发送一个确认报文(ACK=1),确认号为
ack=y+1,序列号为seq=x+1,客户端和服务器进入ESTABLISHED状态,完成三次握手。
为什么不是两次握手
- 防止已过期的连接请求报文突然又传送到服务器,因而产生错误和资源浪费。
在两次握手即可建立连接的情况下,假设客户端发送 A 报文段请求建立连接,但由于网络原因暂时无法到达服务器,客户端会在超时后重新发送请求报文段 B,这次 B 顺利到达服务器,双方建立连接并传输数据,之后正常断开连接。
此时 A 报文段才到达服务器,服务器随即返回确认报文并进入 ESTABLISHED 状态,但是已经进入 CLOSED 状态的客户端无法再接受确认报文段,更无法进入 ESTABLISHED 状态,这将导致服务器长时间单方面等待,造成资源浪费。 - 三次握手才能让双方均确认自己和对方的发送和接收能力都正常。
第一次握手:客户端只是发送处请求报文段,什么都无法确认,而服务器可以确认自己的接收能力和对方的发送能力正常;
第二次握手:客户端可以确认自己发送能力和接收能力正常,对方发送能力和接收能力正常;但服务器方还不能确定自己发送和客户端接收是否正常;
第三次握手:服务器可以确认自己发送能力和接收能力正常,对方发送能力和接收能力正常; - 告知对方自己的初始序号值,并确认收到对方的初始序号值。
TCP 报文段中维护了序号字段和确认序号字段,从而确定发出的数据中哪些已经被对方确认接收。这两个字段的值会在初始序号值得基础递增,如果是两次握手,只有发起方的初始序号可以得到确认,而另一方的初始序号则得不到确认。
三次握手可以携带数据吗
第三次握手可以携带数据的,但是前两次握手不可以
- 第一次握手不可以带数据,因为会让服务器更加容易受到攻击(不断发送SYN,并携带长数据)
- 第三次握手时,客户端已经处于 ESTABLISHED 状态,对客户端来说已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据
TCP的四次挥手

四次挥手过程
- 第一次挥手:客户端向服务端发送连接释放报文(FIN=1,ACK=1),主动关闭连接并等待服务端的确认。
- 序列号
seq = u,即客户端上次发送的报文的最后一个字节的序号 + 1 - 确认号
ack = k, 即服务端上次发送的报文的最后一个字节的序号 + 1
- 序列号
- 第二次挥手:服务端收到连接释放报文后,立即发出确认报文(ACK=1)
- 序列号
seq = k,确认号ack = u + 1。 - 这时 TCP 连接处于半关闭状态,即客户端到服务端的连接已经释放了,但是服务端可能还要给客户端发送数据。
- 序列号
- 第三次挥手:服务端向客户端发送连接释放报文(FIN=1,ACK=1),主动关闭连接,同时等待 A 的确认。
- 序列号
seq = w,即服务端上次发送的报文的最后一个字节的序号 + 1。 - 确认号
ack = u + 1,与第二次挥手相同,因为这段时间客户端没有发送数据
- 序列号
- 第四次挥手:客户端收到服务端的连接释放报文后,立即发出确认报文(ACK=1)
- 序列号
seq = u + 1,确认号为ack = w + 1。 - 此时,客户端就进入了
TIME-WAIT状态,必须经过 2*MSL(最长报文段寿命)的时间后,才进入CLOSED状态。而服务端只要收到客户端发出的确认,就立即进入CLOSED状态。
- 序列号
为什么TIME-WAIT状态等待 2MSL
- 确保 ACK 报文能够到达服务端,从而使服务端正常关闭连接
第四次挥手时,客户端第四次挥手的 ACK 报文不一定会到达服务端。服务端会超时重传 FIN/ACK 报文,此时如果客户端已经断开了连接,那么就无法响应服务端的二次请求,这样服务端迟迟收不到 FIN/ACK 报文的确认,就无法正常断开连接 - 防止已失效的连接请求报文段出现在之后的连接中
客户端在发送完最后一个ACK报文段后,再经过2MSL就可以使本次连接的所有报文段都从网络中消失,使得下一个连接中不会出现旧的报文段
TIME-WAIT状态的危害与优化
危害:
- 占用系统资源:比如文件描述符、内存资源、CPU 资源、线程资源等
- 占用端口资源:若客户端占满了所有端口资源,就无法对「目的 IP+ 目的 PORT」一样的服务端发起连接了
优化:
调整系统内核参数
tcp_tw_reuse选项,超过一秒直接被复用,但仅适用客户端tcp_max_tw_buckets选项,新关闭的连接数超过该参数时直接关闭
调整短连接为长连接
服务器大量 TIME_WAIT 的原因
即服务端主动关闭连接的情况:
HTTP 没有使用长连接
任意一方未开启长连接时,大多数Web服务器的实现都是服务端主动关闭连接
HTTP 长连接超时
HTTP 长连接的请求数量达到上限
没有Accept、Listen还能建立TCP连接吗
没有 accept() 可以
- 每一个
socket执行listen时,内核都会自动创建一个半连接队列(哈希表)和全连接队列(链表)。 - 第三次握手前,TCP连接会放在半连接队列中,直到第三次握手到来,才会被放到全连接队列中。
accept方法只是为了从全连接队列中拿出一条连接,本身跟三次握手几乎毫无关系。
没有 listen() 可以
- 客户端没有半连接队列和全连接队列,但可以通过 一个全局hash 实现自连接或TCP同时打开。例如自连接:客户端在 connect 时会将连接信息放入这个 hash,然后将消息发出,消息经过回环地址重新回到传输层时,根据
IP + 端口从这个全局 hash 中取出信息,成功连接。
TCP的可靠性
如何保证可靠性
- 基于数据块传输 :应用数据被分割成报文段再传输给网络层。
- 对失序数据包重新排序以及去重:将接收到的数据根据序列号排序,并且去掉重复序列号的数据。
- 校验和 : TCP 将保持它首部和数据的检验和。如果收到段的检验和有差错,TCP 将丢弃这个报文段。
- 超时重传 : 当发送方发送数据之后,它启动一个定时器,等待目的端确认收到这个报文段。如果发送端实体在合理的往返时延(RTT)内未收到确认消息,就假设为已丢失并进行重传。
- 流量控制 : 接收方通过TCP头窗口字段告知发送方本方可接收的最大数据量,用以解决发送速率过快导致接收方不能接收的问题。
- 拥塞控制 : 当网络拥塞时,减少数据的发送。
TCP的流量控制
目的是接收方通过TCP头窗口字段告知发送方本方可接收的最大数据量,用以解决发送速率过快导致接收方不能接收的问题,所以流量控制是点对点控制。TCP流量控制通过滑动窗口协议实现。
TCP是全双工协议,双方可以同时通信,所以发送方接收方各自维护一个发送窗和接收窗。
- 发送窗:用来限制发送方可以发送的数据大小,其中发送窗口的大小由接收端返回的TCP报文段中窗口字段来控制,接收方通过此字段告知发送方自己的缓冲(受系统、硬件等限制)大小。
- 接收窗:用来标记可以接收的数据大小。
TCP是流数据,发送出去的数据流被分为四部分:已发送且被确认部分 | 已发送未被确认部分 | 未发送但可发送部分 | 不可发送部分,其中发送窗 = 已发送未确认部分 + 未发但可发送部分。
接收到的数据流分为:已接收 | 未接收但准备接收 | 未接收不准备接收,其中接收窗 = 未接收但准备接收部分。
发送窗只有收到接收端的确认时才向右移动,左边缘紧贴刚被确认的数据。接收窗也只有接收到数据且最左侧连续时才向右移动。
TCP的拥塞控制
在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏,这就叫拥塞。拥塞控制就是为了防止过多的数据注入到网络中,防止路由器或链路过载。拥塞控制是一个全局性的过程,涉及到所有的主机和路由器,以及与降低网络传输性能有关的所有因素。
为了进行拥塞控制,TCP 发送方要维持一个 拥塞窗口(cwnd) 变量,其大小取决于网络的拥塞程度,并且动态变化。发送窗口为拥塞窗口与接收窗口的最小值。
TCP 的拥塞控制采用了四种算法:
- **慢开始:**一开始先发送小量的数据,从小到大成倍增加拥塞窗口的大小,达到慢开始门限后再采用拥塞避免
- **拥塞避免:**每经过一个传输轮次就把 cwnd 加1而不是加倍,这样拥塞窗口按线性规律缓慢增长
- **快重传:**所谓快重传,就是使发送方尽快进行重传,而非等计时器超时才重传。接收方即使收到一个失序的报文段也要立即发出重复确认,而不要等到自己发送数据时捎带确认。发送方只要收到三个连续的重复确认,就立即重传对方尚未收到的报文段,而不必等待计时器超时。
- **快恢复:**当发送方连续收到三个重复确认时,把慢开始门限和 cwnd 调整为当前窗口的一半(为了预防网络发生拥塞),接下来开始执行拥塞避免算法,而非慢开始算法。因为如果网络出现拥塞的话就不会收到好几个重复的确认,收到三个重复确认说明网络状况还可以。
ARQ协议
自动重传请求是数据链路层和传输层的错误纠正协议,通过确认和超时机制实现可靠的信息传输。如果在发送后一段时间之内没有收到确认信息(ACK)就会重新发送,直到收到确认或者重试超过一定的次数。
停止等待ARQ协议
每发完一个分组就停止发送,等待对方确认,超时未接收到确认就重新发送。
连续 ARQ 协议
连续 ARQ 协议可提高信道利用率。发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累计确认,对按序到达的最后一个分组发送确认,表明到这个分组为止之前都正确收到了。
优点: 信道利用率高,容易实现,即使确认丢失,也不必重传。
缺点: 不能向发送方反映出已经正确收到的所有分组的信息。中间几条丢失后,由于接收方只能确认前面几条,所以发送方只能将后边几条也重传。这也叫回退N帧,表示需要退回来重传已经发送过的 N 个消息。
TCP和UDP的区别
首靠序 传连景
| UDP | TCP | |
|---|---|---|
| 是否连接可靠 | 无连接的不可靠传输,不使用流量控制和拥塞控制 | 面向连接的可靠传输,使用流量控制和拥塞控制 |
| 首部开销 | 8Bytes:端口号、长度、校验和 | 20~60Bytes:还包括序列号、确认号、数据偏移量、窗口、紧急指针 |
| 是否有状态、有序 | 无状态、无序 | 有状态(记录发消息的状态,是否发送、被接收)、有序(乱序排序) |
| 传输速度与方式 | 传输快,面向报文,有数据边界 | 传输慢,面向字节流,无数据边界,粘包拆包 |
| 连接对象个数 | 一对一,一对多,多对一和多对多交互通信 | 一对一通信 |
| 适用场景 | 适用于实时应用(视频会议、直播),包总量较少的通信(DNS) | 适用于要求可靠传输(FTP,HTTP) |
UDP如何保证可靠
最简单的方式是在应用层模仿传输层TCP的可靠性传输
- 添加seq/ack机制,确保数据发送到对端
- 添加发送和接收缓冲区,主要是用户超时重传
- 添加超时重传机制
TCP和UDP对应的协议
TCP:
- FTP(21):定义了文件传输协议,控制端口21,数据端口20或协商而定。
- SSH(22): 专为远程登录会话和其他网络服务提供安全性的协议。
- Telnet(23):远程登陆协议是一种用于远程登陆的端口,用户可以以自己的身份远程连接到计算机上,通过这种端口可以提供一种基于DOS模式下的通信服务。
- SMTP(25):定义了简单邮件传送协议,现在很多邮件服务器都用的是这个协议,用于发送邮件。
- POP3(110):它是和SMTP对应,POP3用于接收邮件。
- HTTP(80)协议:是从Web服务器传输超文本到本地浏览器的传送协议。
UDP:
DNS(53):用于域名解析服务,将域名地址转换为IP地址
RIP(520):路由信息协议
TFTP(69):简单文件传输协议
TCP的其他问题
第三次握手的ACK包丢失会发生什么
- 服务端:第三次的 ACK 在网络中丢失,那么服务端的状态为 SYN_RECV,会根据超时重机制不断重发 SYN+ACK 包,等待客户端确认。如果重发超过指定次数仍未收到应答,服务端自动关闭连接。
- 客户端:客户端认为这个连接已经建立,如果客户端向服务端发送数据,服务端将以 RST 包(Reset,标示复位,用于异常的关闭连接)响应。此时,客户端知道第三次握手失败。
建立连接后客户端故障会发生什么(服务端同理)
- 客户端进程崩溃:客户端的进程在发生崩溃的时候,内核会发送 FIN 报文,负责与服务端四次挥手。
- 客户端主机宕机:不会发生四次挥手,后续要看服务端会不会发送数据:
- 如果服务端发送数据,将收不到响应报文,服务端的数据报文会超时重传,当重传总间隔时长达到一定阈值后,会断开 TCP 连接;
- 如果服务端不发送数据,再看服务端有没有开启 TCP keepalive 机制
- 如果有开启,服务端在一段时间没有进行数据交互时,会触发 TCP keepalive 机制,探测对方是否存在,如果探测到对方已经消亡,则会断开自身的 TCP 连接;
- 如果没开启,服务端的 TCP 连接会一直存在,并且一直保持在 ESTABLISHED 状态。
同一个端口能否重复使用
- TCP 和 UDP 可以同时绑定相同的端口吗?
可以。TCP 和 UDP 传输协议,在内核中是由两个完全独立的软件模块实现的。当主机收到数据包后,可以根据IP Header的协议号字段将数据包传到TCP或UDP模块处理,再根据端口号传给对应的应用程序处理。因此 TCP/UDP 各自的端口号也相互独立,互不影响。 - 多个 TCP 服务进程可以绑定同一个端口吗 / 客户端的端口可以重复使用吗?
TCP 连接是由四元组 < 源IP地址,源端口,目的IP地址,目的端口 > 唯一确认的,那么只要四元组中其中一个元素发生了变化,那么就表示不同的 TCP 连接,可以重复使用。 - 客户端 TCP 连接 TIME_WAIT 状态过多,会导致端口资源耗尽而无法建立新的连接吗?
若连接同一个服务器,四元组的目的IP、目的端口、源IP均已固定,而源端口又都被占用,所以不能建立连接
若连接其他服务器,由于目的IP变化,建立的是新TCP连接,就可以复用端口了
同一端口最大 TCP 连接数
服务端:
- 理论:客户端IP数 x 客户端端口数 = 2^48
- 实际:受文件描述符(进程、用户、系统三个级别)、线程并发过多、内存、CPU限制
**客户端:**Chrome 最多允许对同一个 Host 建立六个 TCP 连接,不同的浏览器有区别
TCP粘包和拆包
由于UDP有消息保护边界,不会发生粘包拆包问题。
由于TCP面向字节流传输的,没有消息保护边界。一方发送的多个报文可能会被合并成一个大的报文进行传输,这就是粘包;也可能发送的一个报文,可能会被拆分成多个小报文,这就是拆包。
原因:
- socket缓冲区:数据拷贝到socket的内核缓冲区后可能并不立即发送。
- MSS/MTU限制:分片,见“MTU和MSS“
- Nagle算法:思路是延时处理,发送方一直在囤积数据,只有满足下面任意一个条件,才可以发送数据:
- 条件一:要等到可用窗口大小 >=
MSS并且 可发送数据大小 >=MSS - 条件二:收到之前发送数据的
ack回包
由于当前带宽充裕,TCP/IP协议栈默认关闭Nagle算法
- 条件一:要等到可用窗口大小 >=
解决:
- 在每个包的末尾使用固定的分隔符,例如\n\r,\t。
- 将消息分为头部和消息体,头部中保存整个消息的长度
- 应用层发送数据时定长发送。
Established 状态收到SYN会怎样
一个已经建立的 TCP 连接,客户端中途宕机了,而服务端此时也没有数据要发送,一直处于 Established 状态,客户端恢复后,向服务端建立连接,此时服务端会怎么处理?
1. 客户端的 SYN 报文里的端口号与历史连接不同
服务端会通过三次握手来建立新的连接。而旧连接里处于 Established 状态的服务端最后会:
- 若服务端发送了数据包,此时客户的内核就会回 RST 报文,释放连接。
- 若服务端一直没有发送数据包,一段时间后由 TCP 保活机制探测并释放掉该连接。
2. 客户端的 SYN 报文里的端口号与历史连接相同
处于 Established 状态的服务端收到乱序的 SYN 后(因为初始序列号是随机数),会回复一个携带了正确序列号和确认号的 ACK 报文(Challenge ACK)。接着,客户端收到 Challenge ACK 发现确认号并不是期望的,就会回 RST 报文,服务端收到后释放掉该连接。
TIME-WAIT 状态收到SYN会怎样
合法 SYN:客户端的 SYN 的序列号比服务端期望下一个收到的序列号大
非法 SYN:客户端的 SYN 的序列号比服务端期望下一个收到的序列号要小
- 收到合法 SYN ,就会重用此四元组连接,跳过 2MSL 而转变为
SYN_RECV状态,接着进行建立连接过程 - 收到非法 SYN ,就会再回复一个第四次挥手的 ACK 报文,客户端收到后,发现并不是自己期望收到确认号,就回 RST 报文给服务端
既然IP层会分片,为什么还需要MSS?
- 如果一个 IP 分片丢失,整个 IP 报文的所有分片都得重传。因为IP层没有超时重传机制,由TCP负责的。若某个IP分片丢失,就无法组装成完整的TCP报文交付到TCP层,也就无法发送确认报文。所以发送方只能重传整个TCP报文。
- 而经过 TCP 层分片后,如果一个 TCP 分片丢失后,进行重发时也是以 MSS 为单位,而不用重传所有的分片,大大增加了重传的效率。
ARP与路由
ARP协议
每个主机都存有一个ARP高速缓存,存放本局域网上各主机和路由器的IP地址到MAC地址的映射表,使用ARP协议动态维护此表。
ARP工作在网络层中(但OSI模型中划分在链路层),其工作原理是:当主机A想要向主机B发送IP数据报时,就先在其ARP高速缓存中查看有无主机B的IP地址:
- 如果有,可以查出其对应的MAC地址写入帧,然后通过局域网发往此地址
- 如果没有,就封装一个目的MAC地址为32位全1的帧来广播ARP请求分组。同一个局域网里的所有主机都会收到ARP请求,并检查是否与自己的IP地址匹配,如果不匹配则丢弃ARP请求
- 如果主机B在局域网中,会把A的IP和MAC地址存入自己的ARP表中,再以单播方式发送ARP响应报文给主机A,其中包含了自己的MAC地址,主机A在收到后进行缓存并向此MAC地址发送
- ARP是解决同一个局域网上IP和MAC的映射问题。如果主机B不在一个局域网上,则通过ARP协议找到某个路由器MAC地址,然后把分组发送给这个路由器,从而转发给下一个网络。
路由选择协议
RIP(路由信息协议):基于距离向量的路由选择协议,应用层协议,使用 UDP 传输数据。它选择路由的度量标准是跳数,跳数大于15就丢弃数据包。仅和相邻路由器交换当前路由器所知道的全部信息,定期发送。
- 优点:简单、开销小、收敛快
- 缺点:限制规模、故障收敛慢、子网掩码必须相同(RIP2不用)
OSPF(开放最短路由优先):底层是 Dijkstra 算法,是链路状态路由选择协议,网络层协议,直接IP数据报传输。它选择路由的度量标准是带宽,延迟,计算代价灵活。向本自治系统中所有路由器发送与本路由器相邻的路由器链路状态,但这只是路由器知道的部分信息,只有链路变化才泛洪发送
描述RARP协议
RARP是逆地址解析协议,作用是完成MAC地址到IP地址的映射 (请求是广播,应答是单播)
- 每台设备都有一个独一无二的硬件地址,通常是由设备厂商分配的。主机从网卡上读取MAC地址,然后在网络上发送一个RARP请求的广播数据包,请求RARP服务器分配一个IP地址
- 本地网段上的RARP服务器收到此请求后,检查其RARP列表中是否有该MAC地址对应的IP地址,如果有就返回,否则不做任何的响应
- 如果一直没有收到RARP服务器的响应信息,则初始化失败
交换机、路由器和网关
简介
- 路由器:多个输入输出端口的专用计算机,其任务是连接不同的网络并完成路由转发。当源主机向目标主机发送数据报时,路由器先检查源主机与目标主机是否连接在一个网络上,如果在一个网络上则直接交付,否则根据路由器转发表将数据报转发给下一个路由器,即间接交付。路由器隔离了广播域
- 交换机:多个端口的网桥,其任务是连接多个以太网成为更大的以太网。它能隔离冲突域,为每个工作站提供更高的带宽。其原理是,检测数据帧的MAC地址,然后与系统内部的动态查找表进行比较。若数据帧的MAC地址不在查找表中,则将该地址加入查找表中,并将数据帧发送给相应的端口
区别
- 路由器:工作在网络层,连接不同的广域网形成更大的广域网,连接的是异构网络。根据IP地址转发
- 交换机:工作在数据链路层,连接以太网形成更大的以太网,同一个网络。根据MAC地址进行转发
- 网关:网关在网络层以上实现网络互连,仅用于两个高层协议不同的网络互连。网关既可以用于广域网互连,也可以用于局域网互连。 网关是一种充当转换重任的计算机系统或设备,使用在不同的通信协议、数据格式的两种系统之间,是一个翻译器
DNS
DNS:域名系统,一个域名和IP地址相互映射的分布式数据库,能让用户更方便的访问互联网而不用去记IP地址
域名解析:通过域名得到对应的IP的过程,应用层协议,底层基于UDP和TCP协议
- TCP:辅域名服务器定时向主域名服务器查询数据有变化,若有则用TCP传输同步(同步的数据量大)
- UDP:客户端向DNS服务器查询域名(一般返回不超过512B,UDP省去了三次握手,减小服务器压力)
解析过程
递归查询:主机和本地DNS服务器之间
迭代查询:本地DNS服务器和根/顶级/权限域名服务器之间
- 查找浏览器、操作系统(host文件)、路由器缓存中有无域名对应的DNS解析结果
- 查询本地域名服务器中有无缓存,如果没有就直接查询根域名服务器。根域名服务器返回一个顶级域名服务器地址如
.com、.cn等 - 本地域名服务器再查询顶级域名服务器。顶级域名服务器返回对应的权限域名服务器的地址(可能有多级)
- 本地域名服务器再查询权限域名服务器,最终查询出来的IP地址和TTL值(缓存时间)返回给本地域名服务器
- 本地域名服务器缓存IP映射关系,再把解析结果返回给本地电脑,缓存在本地系统缓存中
PING
Ping的工作原理
ping 命令执行的时候,源主机会发送 ICMP 回送请求消息,目的主机返回 ICMP 回送响应消息。在规定的时候间内,源主机如果没有接到 ICMP 的应答包,则说明目标主机不可达;如果接收到了则说明可达,此时源主机会用当前时刻减去该数据包最初从源主机上发出的时刻,得到 ICMP 数据包的时间延迟。
几个地址的区别
127.0.0.1:回环地址,与ping本机IP地址的效果一致localhost:是域名,默认映射为127.0.0.10.0.0.0- 在IPV4中,0.0.0.0地址无效,因此不能ping通。
- 在服务器中,若一个服务监听的地址是0.0.0.0,则指的是本机上的所有IPV4地址。例如一个主机有两个IP地址,则通过这两个ip地址都能够访问该服务。
- 在路由中,0.0.0.0表示的是默认路由。
为什么断网还能Ping通127.0.0.1、本机地址
到了网络层转发时,发现目标 IP 是回环地址,就不会送到”真网卡”的ring buffer中,而是选择本地网卡,它会把数据推到一个链表后就会触发一个软中断,由内核线程会去链表里把消息取出,然后顺着数据链路层、网络层等层层往上传递最后给到应用程序。因此消息发到这个地址上就不会出网络,在本机打个转就又回来了。
HTTP
GET和POST的区别
使用区别:
- GET使用URL或Cookie传参,有长度限制,而POST将数据放在BODY中可以很大
- POST比GET安全,因为数据在地址栏上不可见(但在 HTTP 下都不安全,因为明文传输可以被抓包)
- GET产生一个TCP数据包,将
http header和data一并发送出去,服务器响应200 ok(返回数据);POST产生两个TCP数据包,浏览器先发送header,服务器响应100 continue,再发送data,服务器响应200 ok(返回数据)。不过 POST 分开发送是部分浏览器或框架的请求方法,并不是必然行为 - GET请求会被浏览器主动缓存,而POST不会,除非手动设置
本质区别:
GET是幂等的,而POST不是幂等的。幂等性是指一次和多次请求某一个资源应该具有同样的副作用,即对同一URL的多个请求应该返回同样的结果。所以不应该 GET 请求做数据的增删改操作,因为 GET 请求是幂等的,在网络不好的隧道中会尝试重试,有重复操作的风险。
HTTP状态码

- 301:(永久移动) 请求的网页已永久移动到新位置。服务器返回此响应时,会自动将请求者转到新位置
- 302:(临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求
- 401:(未授权) 请求要求进行身份验证
- 403:(禁止) 服务器收到请求,但是拒绝提供服务
- 404:(未找到) 服务器找不到请求的网页
- 409:(Conflict) 表示请求的资源与资源的当前状态发生冲突
- 410:(Gone) 资源被永久性的删除
- 503:(服务不可用) 无法使用服务器,由于超载或进行停机维护,一般是暂时的
- 504:(网关超时) 服务器作为网关,未及时从上游服务器接收请求
HTTP请求方式
| 序号 | 方法 | 描述 |
|---|---|---|
| 1 | GET | 请求指定资源并返回主体。 |
| 2 | HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
| 3 | POST | 向指定资源提交数据进行处理请求,数据被包含在请求体中。可能会创建资源或已有资源修改 |
| 4 | PUT | 提交数据并替代已有资源,若不存在则创建(必须明确知道要操作的对象,幂等性) |
| 5 | DELETE | 请求服务器删除指定资源 |
| 6 | CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。 |
| 7 | OPTIONS | 允许客户端查看服务器的性能 |
| 8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断 |
| 9 | PATCH | 是对 PUT 方法的补充,用来对已知资源进行局部更新 |
HTTP报文格式
请求格式:
- 请求行(请求方法+URL+协议版本)
GET /sample.jsp HTTP/1.1 - 请求头部
- 空行
- 请求主体
响应报文:
- 状态行(协议版本+状态码+状态码描述)
HTTP/1.1 200 OK - 响应首部
- 空行
- 响应主体
HTTP1.0和HTTP1.1的区别
- 长连接:HTTP1.1 默认开启
Connection:keep-alive,支持长连接和请求的流水线处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,弥补了HTTP1.0每次请求都要创建连接的缺点。 - 缓存处理:HTTP1.1 则引入了更多的缓存控制策略,提供了更多可选择的缓存头来控制缓存策略。
- 带宽优化及网络连接的使用:HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能。HTTP1.1则在请求头引入了range头域,允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
- 状态响应码:在 HTTP1.1 中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
- Host头处理:在 HTTP1.0 中认为每台服务器都绑定一个唯一的 IP 地址,因此,请求消息中的URL并没有传递主机名。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机,它们共享一个IP地址。所以 HTTP1.1 的请求消息和响应消息都应支持Host头域,请求消息中如果没有Host头域会报 400 错误。
HTTP2相比HTTP1.1的改进
- 头部压缩:如果同时发出多个请求且header相似,协议会压缩帮助消除重复的部分
- 二进制格式:HTTP2 不像 HTTP1.1 的纯文本形式,而是采用了二进制格式,增加了数据传输的效率。
- 并发传输:HTTP1.1 基于请求-响应模型,同一个连接中要完成一个事务才能处理下一个事务,容易阻塞。而 HTTP2 引入了帧、消息和数据流,每个请求/响应为消息、每个消息被分成若干帧,各个帧在流和连接上独立传输,到达之后再组装成消息。HTTP2 将多个流复用在一条 TCP 连接,可以并行交错地发送请求和响应。
- 服务器推送:服务端不再是被动地响应,可以主动向客户端发送消息。
HTTP长连接和短连接
- HTTP1.0 默认使用短连接。浏览器和服务器每进行一次HTTP操作就建立一次连接,任务结束就中断连接。如果客户端请求频繁的话,会在TCP的建立和释放上浪费大量的时间
- HTTP1.1 起默认使用长连接,会在响应头加入:
Connection:keep-alive。当一个网页打开完成后,客户端和服务器之间传输HTTP数据的TCP连接不会关闭,等下次时还会用这条连接,从而节省TCP连接和释放的时间。Keep-Alive不会永久保持连接,它的保持时间可以在不同的服务器软件中设定。实现长连接要客户端和服务端都支持长连接。
HTTP和TCP的Keep-Alive区别
- HTTP 的 Keep-Alive 也叫 HTTP 长连接,该功能是由应用程序实现的,可以使得用同一个 TCP 连接来发送和接收多个 HTTP 请求/应答,减少了 HTTP 短连接带来的多次 TCP 连接建立和释放的开销。
- TCP 的 Keepalive 也叫 TCP 保活机制,该功能是由内核实现的,当客户端和服务端长达一定时间没有进行数据交互时,内核就会发送探测报文,若对方不在线则关闭该连接。
HTTP和HTTPS的区别
| HTTP | HTTPS | |
|---|---|---|
| 连接很简单,无状态 | SSL+HTTP协议构建的可加密传输、身份认证的协议 | |
| 端口 | 80 | 443 |
| 是否证书 | 不需要 | 需要 |
| 安全性 | 信息无加密传输,安全性较差 | 采用对称加密,安全性高 对称加密的密钥是用服务器证书进行非对称加密的 |
| 资源消耗 | 响应快,资源消耗较少 | 由于加密处理,响应慢、资源消耗多 |
| 协议 | 运行在TCP协议之上 | 运行在SSL协议之上,SSL运行在TCP协议之上 |
HTTPS的原理/流程(SSL是怎么保证安全的)

- 客户端请求 HTTPS 网址连接443 端口,将 SSL 协议版本的信息发送给服务端
- 采用 HTTPS 协议的服务器必须要有一套数字 CA 证书。颁发证书的同时会产生一个私钥和公钥。私钥由服务端自己保存,不可泄漏,公钥则是附带在证书的信息中,可以公开。证书本身也附带一个证书电子签名,用来验证证书的完整性和真实性,防止被篡改
- 服务器响应客户端请求,将证书传递给客户端,证书包含公钥和大量其他信息,比如证书颁发机构信息,公司信息和证书有效期等
- 客户端解析证书并对其进行验证。如果证书的机构不可信、域名不一致或证书过期,就会向访问者显示警告;如果证书没问题,客户端就会从证书中取出服务器的公钥A
双向认证还需:
- 客户端将客户端公钥证书发送给服务器端
- 服务器端使用根证书解密客户端公钥证书,拿到客户端公钥
- 客户端发送自己支持的加密方案,服务器端选择一个,并使用客户端的公钥加密后发送给客户端
- 客户端使用自己的私钥解密加密方案
- 客户端生成一个随机码 KEY,并使用公钥A加密发送给服务器,作为后面对称加密的密钥
- 服务器在收到随机码 KEY 之后会使用私钥B将其解密。经过以上这些步骤,客户端和服务器终于建立了安全连接,防止了对称加密的密钥泄露,接下来就可以用对称加密进行通信了
- 服务器使用密钥 (随机码 KEY) 对数据进行对称加密并发送给客户端,客户端使用相同的密钥解密
- 双方使用对称加密传输所有数据
HTTP缓存
- 强制缓存:只要浏览器判断缓存没有过期,就直接使用浏览器的本地缓存,而不需要再发送请求获取资源。决定是否使用缓存的主动性在于浏览器。
- 协商缓存:协商缓存是一种服务端的缓存策略,即通过服务端来判断是不是可以被缓存。接收到浏览器请求之后,服务器如果判断资源一致,则返回
304告知使用浏览器缓存,否则返回 200 和最新的资源 - 优先级:强制缓存 > 协商缓存
HTTPS的优缺点
优点:
- 使用HTTPS协议可认证用户和服务器,确保数据发送到正确的客户机和服务器
- HTTPS协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全,可防止数据被窃取、改变,确保完整性。
- HTTPS是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。
缺点:
- HTTPS 比 HTTP 的响应时间、耗电量、服务器资源更高,成本更高。
- 安全是有范围的,在黑客攻击、服务器劫持等情况下几乎起不到作用,依然可能遭受中间人攻击。
Cookie与Session
什么是Cookie
HTTP 协议是无状态的,所以HTTP1.1 引入 Cookie 来保存状态信息。
Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器之后向同一服务器再次发起请求时被携带上,用于告知服务端两个请求是否来自同一浏览器。
Cookie 曾一度用于客户端数据的存储,但现在随着现代浏览器开始支持各种各样的存储方式(本地存储和会话存储),Cookie 渐渐被淘汰。
用途
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
什么是Session
Session 代表着服务器和客户端一次会话的过程。Session 对象存储特定用户会话所需的属性及配置信息。
这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当客户端关闭会话,或者 Session 超时失效时会话结束。
Session 可以存储在服务器上的文件、数据库或者内存中,也可以存储在 Redis 这种内存型数据库中,效率更高。
Cookie和Session的工作原理
用户第一次请求服务器时,服务器创建 Session ,请求返回时将 SessionID 返回给浏览器,浏览器将 SessionID 和对应的域名存入到 Cookie 中。
用户以后访问服务器的时候,自动判断此域名下是否存在 Cookie 信息,如果存在就将 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息。如果没有找到说明用户没有登录或者登录失效,否则说明用户已经登录可执行后面操作。
SessionID 是连接 Cookie 和 Session 的桥梁,大部分系统也是根据此原理来验证用户登录状态。所以不能产生一个容易被猜到的 SessionID 值,防止被攻击者轻易获取。
Cookie和Session的区别
- 作用范围不同,Cookie 保存在客户端,Session 保存在服务器端。
- 存取方式的不同,Cookie 只能保存 ASCII,Session 可以存任意数据类型。
- 存储大小不同,单个 Cookie 不能超过 4K,Session 可存储数据远高于 Cookie。
- 有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。
- 隐私策略不同,Cookie 存储在客户端容易被窃取,Session 存储在服务端安全性要好一些。
概念了解
SQL注入
在用户输入的字符串中加入 SQL 语句,如果程序中忽略了检查,这些注入的 SQL 语句就会被数据库服务器误认为是正常的 SQL 语句而运行,攻击者就可以执行计划外的命令或访问未被授权的数据。
例如,输入用户名为 alice'-- 或 alice' or '1'='1 跳过密码检查
1 | -- 原语句 |
避免:
- 限制数据库权限,给用户提供仅仅能够满足其工作的最低权限。
- 对进入数据库的特殊字符转义处理。
- 提供参数化查询接口,不直接使用原生SQL。
Dos攻击
拒绝服务攻击。发送大量恶意数据包,占用目标主机的资源,导致需要正常访问的数据包得不到及时的处理,网络延迟过高、甚至无法响应。
DDoS攻击
分布式拒绝服务攻击,将多个计算机联合起来作为一个攻击平台发起攻击,原理、检测和预防同SYN洪泛
SYN洪泛攻击
利用 TCP 协议缺陷,通过发送大量的半连接请求,耗费 CPU 和内存资源。
原理:
- 在 TCP 三次握手过程中,服务器发送完
[SYN/ACK]包、收到[ACK]包之前称为半连接,此时服务器处于SYN_RECV(等待客户端响应)状态。如果接收不到到客户端的[ACK],就会不断重发请求。 - SYN 攻击的攻击者向服务器不断地发送
[SYN]包,服务器产生大量半连接等待客户的确认,占用未连接队列,影响了正常的 SYN,导致目标系统运行缓慢、网络堵塞甚至系统瘫痪。
检测:服务器上有大量的半连接且源 IP 地址是随机的,则很可能是 SYN 攻击。
预防:
- 限制同时打开SYN半链接的数目
- 缩短SYN Time out 时间
- 通过防火墙、路由器等过滤网关防护
CSRF攻击
跨站点请求伪造,指攻击者通过跨站请求,以合法的用户的身份进行非法操作。比如攻击者盗用你的身份,以你的名义向第三方网站发送恶意请求。包括利用你的身份发邮件,发短信,进行交易转账,甚至盗取账号信息。
解决:token验证,服务器生成一个随机字符串保存在session中,并作为token返回给客户端,以隐藏的形式保存在客户端中,客户端每次请求都会带着这个token,服务器根据该token判断该请求是否合法
XSS攻击
跨站点脚本攻击,指攻击者通过篡改网页,嵌入恶意脚本程序,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式
防范:核心是对输入的数据做过滤处理。限制字符串输入的长度,对HTML转义处理,将其中的”<”,”>”等特殊字符进行转义编码
RTO和RTT
- RTO:重传间隔,每次翻倍,重传次数到达上限之后停止重传
- RTT:往返时延
URI和URL
- URI:
Uniform Resource Identifier,统一资源标志符,可以唯一标识一个资源。 - URL:
Uniform Resource Locator,统一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。
MTU和MSS
MTU:
maximum transmission unit,最大传输单元,由硬件规定,如以太网的MTU为1500字节。MSS:
maximum segment size,最大分节大小,为TCP数据包传输的最大数据分段大小,一般由对端TCP通知。MSS值为MTU值减去IPv4 Header(20B)和TCP header(20B)得到