目录
[53 简述epoll和select的区别,epoll为什么高效?](#53 简述epoll和select的区别,epoll为什么高效?)
[54 说说多路IO复用技术有哪些,区别是什么?](#54 说说多路IO复用技术有哪些,区别是什么?)
[55 简述socket中select,epoll的使用场景和区别,epoll水平触发与边缘触发的区别?](#55 简述socket中select,epoll的使用场景和区别,epoll水平触发与边缘触发的区别?)
[57 简述同步与异步的区别,阻塞与非阻塞的区别?](#57 简述同步与异步的区别,阻塞与非阻塞的区别?)
[58 BIO、NIO有什么区别?](#58 BIO、NIO有什么区别?)
[59 请介绍一下5种IO模型](#59 请介绍一下5种IO模型)
[60 请说一下socket网络编程中客户端和服务端用到哪些函数?](#60 请说一下socket网络编程中客户端和服务端用到哪些函数?)
[61 简述网络七层参考模型,每一层的作用?](#61 简述网络七层参考模型,每一层的作用?)
[3.1 简述静态路由和动态路由](#3.1 简述静态路由和动态路由)
[3.2 说说有哪些路由协议,都是如何更新的](#3.2 说说有哪些路由协议,都是如何更新的)
[3.5 简述网关的作用是什么,同一网段的主机如何通信](#3.5 简述网关的作用是什么,同一网段的主机如何通信)
[3.8 简述 TCP 三次握手和四次挥手的过程](#3.8 简述 TCP 三次握手和四次挥手的过程)
[3.9 说说 TCP 2次握手行不行?为什么要3次](#3.9 说说 TCP 2次握手行不行?为什么要3次)
[3.10 简述 TCP 和 UDP 的区别,它们的头部结构是什么样的](#3.10 简述 TCP 和 UDP 的区别,它们的头部结构是什么样的)
[3.11 简述 TCP 连接 和 关闭的具体步骤](#3.11 简述 TCP 连接 和 关闭的具体步骤)
[3.12 简述 TCP 连接 和 关闭的状态转移](#3.12 简述 TCP 连接 和 关闭的状态转移)
[3.13 简述 TCP 慢启动](#3.13 简述 TCP 慢启动)
[3.14 说说 TCP 如何保证有序](#3.14 说说 TCP 如何保证有序)
[3.15 说说 TCP 常见的拥塞控制算法有哪些](#3.15 说说 TCP 常见的拥塞控制算法有哪些)
[3.16 简述 TCP 超时重传](#3.16 简述 TCP 超时重传)
[3.17 说说 TCP 可靠性保证](#3.17 说说 TCP 可靠性保证)
[3.18 简述 TCP 滑动窗口以及重传机制](#3.18 简述 TCP 滑动窗口以及重传机制)
[3.19 说说滑动窗口过小怎么办](#3.19 说说滑动窗口过小怎么办)
[3.20 说说如果三次握手时候每次握手信息对方没收到会怎么样,分情况介绍](#3.20 说说如果三次握手时候每次握手信息对方没收到会怎么样,分情况介绍)
[3.21 简述 TCP 的 TIME_WAIT,为什么需要有这个状态](#3.21 简述 TCP 的 TIME_WAIT,为什么需要有这个状态)
[3.22 简述什么是 MSL,为什么客户端连接要等待2MSL的时间才能完全关闭](#3.22 简述什么是 MSL,为什么客户端连接要等待2MSL的时间才能完全关闭)
[3.23 说说什么是 SYN flood,如何防止这类攻击?](#3.23 说说什么是 SYN flood,如何防止这类攻击?)
[3.25 说说 TCP 与 UDP 在网络协议中的哪一层,他们之间有什么区别?](#3.25 说说 TCP 与 UDP 在网络协议中的哪一层,他们之间有什么区别?)
[3.26 说说从系统层面上,UDP 如何保证尽量可靠?](#3.26 说说从系统层面上,UDP 如何保证尽量可靠?)
[3.27 说一说 TCP 的 keepalive,以及和 HTTP 的 keepalive 的区别?](#3.27 说一说 TCP 的 keepalive,以及和 HTTP 的 keepalive 的区别?)
[3.28 简述 TCP 协议的延迟 ACK 和累计应答](#3.28 简述 TCP 协议的延迟 ACK 和累计应答)
[3.29 说说 TCP 如何加速一个大文件的传输](#3.29 说说 TCP 如何加速一个大文件的传输)
[3.30 服务器怎么判断客户端断开了连接](#3.30 服务器怎么判断客户端断开了连接)
[3.31 说说端到端,点到点的区别](#3.31 说说端到端,点到点的区别)
1计算机网络
53简述epoll和select****的区别,epoll为什么高效?
参考回答
- 区别 :
(1)每次调用 select ,都需要把 fd 集合从用户态拷贝到内核态 ,这个开销在 fd 很多时会很大;而
epoll 保证了每个 fd 在整个过程中只会拷贝一次。
(2)每次调用 select 都需要在内核 遍历传递进来的所有 fd ;而 epoll 只需要 轮询一次 fd 集合,同时
查看就绪链表中有没有就绪的 fd 就可以了。
(3) select 支持的文件描述符数量太小了,默认是 1024 ;而 epoll 没有这个限制 ,它所支持的 fd 上
限是最大可以打开文件的数目,这个数字一般远大于 2048 。 - epoll 为什么高效 :
交替。而 epoll 只要判断一下就绪链表是否为空就行了,这节省了大量的 CPU 时间。
(2) select , poll 每次调用都要把 fd 集合从用户态往内核态拷贝一次,并且要把当前进程往设备等
待队列中挂一次,而 epoll 只要一次拷贝,而且把当前进程往等待队列上挂也只挂一次,这也能节省
不少的开销。
54说说多路IO****复用技术有哪些,区别是什么?
参考回答
- select , poll , epoll 都是 IO 多路复用的机制, I/O 多路复用就是通过一种机制,可以监视多个文件描述符,一旦某个文件描述符就绪(一般是读就绪或者写就绪),能够通知应用程序进行相应的读写操作。
- 区别 :
(1) poll 与 select 不同,通过一个 pollfd 数组向内核传递需要关注的事件,故没有描述符个数的限
制, pollfd 中的 events 字段和 revents 分别用于标示关注的事件和发生的事件,故 pollfd 数组只需要
被初始化一次。
(2) select , poll 实现需要自己不断轮询所有 fd 集合,直到设备就绪,期间可能要睡眠和唤醒多次
交替。而 epoll 只要判断一下就绪链表是否为空就行了,这节省了大量的 CPU 时间。
(3) select , poll 每次调用都要把 fd 集合从用户态往内核态拷贝一次,并且要把当前进程往设备等
待队列中挂一次,而 epoll 只要一次拷贝,而且把当前进程往等待队列上挂也只挂一次,这也能节省
不少的开销。
55简述socket中select**,epoll的使用场景和区别,epoll水平触发****与边缘触发的区别?**
- select , epoll 的使用场景 :都是 IO 多路复用的机制,应用于高并发的网络编程的场景。 I/O 多路复用就是通过一种机制,可以监视多个文件描述符,一旦某个文件描述符就绪(一般是读就绪或者写就绪),能够通知应用程序进行相应的读写操作。
- select , epoll 的区别 :
(1)每次调用 select ,都需要把 fd 集合从用户态拷贝到内核态,这个开销在 fd 很多时会很大;而
epoll 保证了每个 fd 在整个过程中只会拷贝一次。
(2)每次调用 select 都需要在内核遍历传递进来的所有 fd ;而 epoll 只需要轮询一次 fd 集合,同时
查看就绪链表中有没有就绪的 fd 就可以了。
(3) select 支持的文件描述符数量太小了,默认是 1024 ;而 epoll 没有这个限制,它所支持的 fd 上
限是最大可以打开文件的数目,这个数字一般远大于 2048 。 - epoll 水平触发与边缘触发的区别
LT 模式(水平触发)下,只要这个 fd 还有数据可读,每次 epoll_wait 都会返回它的事件,提醒用户
程序去操作;而在ET (边缘触发)模式中, 它只会提示一次 ,直到下次再有数据流入之前都不会再提示了,无论fd中是否还有数据可读。
56 说说 Reactor 、 Proactor 模式。
参考回答
在高性能的 I/O 设计中,有两个比较著名的模式 Reactor 和 Proactor 模式,其中 Reactor 模式用于同步 I/O ,而 Proactor 运用于异步 I/O 操作。 - Reactor 模式 : Reactor 模式应用于 同步 I/O 的场景 。 Reactor 中读操作的具体步骤如下:
读取操作:
(1)应用程序注册读就需事件和相关联的事件处理器
(2)事件分离器等待事件的发生
(3)当发生读就需事件的时候,事件分离器调用第一步注册的事件处理器
(4)事件处理器首先执行实际的读取操作,然后根据读取到的内容进行进一步的处理 - Proactor 模式 : Proactor 模式应用于 异步 I/O 的场景 。 Proactor 中读操作的具体步骤如下:
(1)应用程序初始化一个异步读取操作,然后注册相应的事件处理器,此时事件处理器不关注读
取就绪事件,而是关注读取完成事件,这是区别于 Reactor 的关键。
(2)事件分离器等待读取操作完成事件
(3)在事件分离器等待读取操作完成的时候,操作系统调用内核线程完成读取操作,并将读取的
内容放入用户传递过来的缓存区中。这也是区别于 Reactor 的一点, Proactor 中,应用程序需要传
递缓存区。
(4)事件分离器捕获到读取完成事件后,激活应用程序注册的事件处理器,事件处理器直接从缓
存区读取数据,而不需要进行实际的读取操作。 - 区别 :从上面可以看出, Reactor 中需要 应用程序自己读取或者写入数据 ,而 Proactor 模式中, 应用程序不需要用户再自己接收数据,直接使用就可以了,操作系统会将数据从内核拷贝到用户区
答案解析
IO 模型的类型。
(1)阻塞 IO :调用者调用了某个函数,等待这个函数返回,期间什么也不做,不停的检查这个函数有 没有返回,必须等这个函数返回后才能进行下一步动作。
(2)非阻塞 IO :非阻塞等待,每隔一段时间就去检查 IO 事件是否就绪。没有就绪就可以做其他事情。
(3)信号驱动 IO : Linux 用套接口进行信号驱动 IO ,安装一个信号处理函数,进程继续运行并不阻塞,当IO 事件就绪,进程收到 SIGIO 信号,然后处理 IO 事件。
(4) IO 多路复用: Linux 用 select/poll 函数实现 IO 复用模型,这两个函数也会使进程阻塞,但是和阻塞IO所不同的是这两个函数可以同时阻塞多个 IO 操作。而且可以同时对多个读操作、写操作的 IO 函数进行检查。知道有数据可读或可写时,才真正调用IO 操作函数。
(5)异步 IO : Linux 中,可以 调用 aio_read 函数告诉内核描述字缓冲区指针和缓冲区的大小、文件偏移及通知的方式,然后立即返回,当内核将数据拷贝到缓冲区后,再通知应用程序。用户可以直接去使用数据。 前四种模型-- 阻塞 IO 、非阻塞 IO 、多路复用 IO 和信号驱动 IO 都属于 同步模式 ,因为其中真正的 IO 操作 ( 函数) 都将会阻塞进程,只有 异步 IO 模型 真正实现了 IO 操作的异步性。
57****简述同步与异步的区别,阻塞与非阻塞的区别?
参考回答
- 同步与异步的区别 :
同步 :是所有的操作都做完,才返回给用户结果。即 写完数据库 之后, 再响应用户 ,用户体验不
好。
异步 :不用等所有操作都做完,就响应用户请求。即 先响应用户请求 ,然后 慢慢去写数据库 ,用户
体验较好。 - 阻塞与非阻塞的区别 :
阻塞 :调用者调用了某个函数,等待这个函数返回,期间什么也不做,不停的检查这个函数有没有
返回,必须等这个函数返回后才能进行下一步动作。
非阻塞 :非阻塞等待,每隔一段时间就去检查 IO 事件是否就绪。没有就绪就可以做其他事情。
58 BIO**、NIO有什么区别?**
参考回答
BIO ( Blocking I/O ) : 阻塞 IO 。调用者调用了某个函数,等待这个函数返回,期间什么也不做,不停的检查这个函数有没有返回,必须等这个函数返回后才能进行下一步动作。
NIO ( New I/O ) : 同时支持阻塞与非阻塞模式 , NIO 的做法是叫一个线程不断的轮询每个 IO 的状态,看看是否有IO 的状态发生了改变,从而进行下一步的操作。
59请介绍一下5种IO****模型
参考回答
- 阻塞 IO :调用者调用了某个函数,等待这个函数返回,期间什么也不做,不停的检查这个函数有没有返回,必须等这个函数返回后才能进行下一步动作。
- 非阻塞 IO :非阻塞等待,每隔一段时间就去检查 IO 事件是否就绪。没有就绪就可以做其他事情。
- 信号驱动 IO : Linux 用套接口进行信号驱动 IO ,安装一个信号处理函数,进程继续运行并不阻塞,当IO 事件就绪,进程收到 SIGIO 信号,然后处理 IO 事件。
- IO 多路复用: Linux 用 select/poll 函数实现 IO 复用模型,这两个函数也会使进程阻塞,但是和阻塞
IO 所不同的是这两个函数可以同时阻塞多个 IO 操作。而且可以同时对多个读操作、写操作的 IO 函数进行检查。知道有数据可读或可写时,才真正调用IO 操作函数。 - 异步 IO : Linux 中,可以调用 aio_read 函数告诉内核描述字缓冲区指针和缓冲区的大小、文件偏移及通知的方式,然后立即返回,当内核将数据拷贝到缓冲区后,再通知应用程序。用户可以直接去 使用数据。
答案解析
前四种模型 -- 阻塞 IO 、非阻塞 IO 、多路复用 IO 和信号驱动 IO 都属于 同步模式 ,因为其中真正的 IO 操作 ( 函数) 都将会阻塞进程,只有 异步 IO 模型 真正实现了 IO 操作的异步性。
异步和同步的区别就在于 ,异步是内核将数据拷贝到用户区,不需要用户再自己接收数据,直接用就可以了,而同步是内核通知用户数据到了,然后用户自己调用相应函数去接收数据
60请说一下socket****网络编程中客户端和服务端用到哪些函数?
参考回答
- 服务器端函数 :
(1) socket 创建一个套接字
(2) bind 绑定 ip 和 port
(3) listen 使套接字变为可以被动链接
(4) accept 等待客户端的链接
(5) write/read 接收发送数据
(6) close 关闭连接 - 客户端函数 :
(1)创建一个 socket ,用函数 socket()
(2) bind 绑定 ip 和 port
(3)连接服务器,用函数 connect()
(4)收发数据,用函数 send() 和 recv() ,或 read() 和 write()
(5) close 关闭连接
61****简述网络七层参考模型,每一层的作用?
3.1****简述静态路由和动态路由
参考回答
- 静态路由是由 系统管理员设计与构建的路由表规定的路由 。适用于 网关数量有限的场合,且网络拓朴结构不经常变化的网络 。其 缺点 是不能动态地适用网络状况的变化,当 网络状况变化后必须由网络管理员修改路由表。
- 动态路由是 由路由选择协议而动态构建的 ,路由协议之间通过交换各自所拥有的路由信息实时更新路由表的内容。动态路由 可以自动学习网络的拓朴结构,并更新路由表 。其缺点是路由广播更新信息将占据大量的网络带宽。
3.2****说说有哪些路由协议,都是如何更新的
参考回答
- 路由可分为静态 & 动态路由。静态路由由管理员手动维护;动态路由由路由协议自动维护。
路由选择算法的必要步骤:
1 )向其它路由器传递路由信息;
2 )接收其它路由器的路由信息;
3 )根据收到的路由信息计算出到每个目的网络的最优路径,并由此生成路由选择表;
4 )根据网络拓扑的变化及时的做出反应,调整路由生成新的路由选择表,同时把拓扑变化以路由
信息的形式向其它路由器宣告。两种主要算法: 距离向量法 ( Distance Vector Routing )和 链路状态算法 ( Link-State Routing)。由此可分为距离矢量(如:RIP 、 IGRP 、 EIGRP ) & 链路状态路由协议(如: OSPF 、 IS-IS )。 路由协议是路由器之间实现路由信息共享的一种机制,它允许路由器之间相互交换和维护各 自的路由表。当一台路由器的路由表由于某种原因发生变化时,它需要及时地将这一变化通 知与之相连接的其他路由器,以保证数据的正确传递。路由协议不承担网络上终端用户之间 的数据传输任务。 - 1 ) RIP 路由协议: RIP 协议最初是为 Xerox 网络系统的 Xerox parc 通用协议而设计的,是
Internet 中常用的 路由协议。 RIP 采用距离向量算法,即路由器根据距离选择路由,所以也称为距
离向量协议。 路由器收集所有可到达目的地的不同路径,并且保存有关到达每个目的地的最少站点数的路 径信息,除到达目的地的最佳路径外,任何其它信息均予以丢弃。同时路由器也把所收集的 路由信息用 RIP 协议通知相邻的其它路由器。这样,正确的路由信息逐渐扩散到了全网。 RIP 使用 非常广泛,它简单、可靠,便于配置。但是 RIP 只适用于小型的同构网络,因 为它允许的最大站点 数为 15 ,任何超过 15 个站点的目的地均被标记为不可达。而且 RIP 每 隔 30s 一次的路由信息广 播也是造成网络的广播风暴的重要原因之一。
2 ) OSPF 路由协议: 0SPF 是一种基于链路状态的路由协议,需要每个路由器向其同一管理域的所 有其它路 由器发送链路状态广播信息。在 OSPF 的链路状态广播中包括所有接口信息、所有的量度 和 其它一些变量。利用 0SPF 的路由器首先必须收集有关的链路状态信息,并根据一定的算法 计算 出到每个节点的最短路径。而基于距离向量的路由协议仅向其邻接路由器发送有关路由 更新信息。 与 RIP 不同, OSPF 将一个自治域再划分为区,相应地即有两种类型的路由选择方式: 当源和目的 地在同一区时,采用区内路由选择;当源和目的地在不同区时,则采用区间路由 选择。这就大大减 少了网络开销,并增加了网络的稳定性。当一个区内的路由器出了故障时 并不影响自治域内其它区 路由器的正常工作,这也给网络的管理、维护带来方便。
3 ) BGP 和 BGP4 路由协议: BGP 是为 TCP / IP 互联网设计的外部网关协议,用于多个自治域之
间。它既不是基于纯 粹的链路状态算法,也不是基于纯粹的距离向量算法。它的主要功能是与其它自治域的 BGP 交换网络可达信息。各个自治域可以运行不同的内部网关协议。 BGP 更新信息包括网络号/自治域路径的成对信息。自治域路径包括到达某个特定网络须经过的自治域串,这些更新信 息通过 TCP 传送出去,以保证传输的可靠性。为了满足 Internet 日益扩大的需要, BGP 还在不断地发展。在最新的 BGP4 中,还可以 将相似路由合并为一条路由。
4 ) IGRP 和 EIGRP 协议: EIGRP 和早期的 IGRP 协议都是由 Cisco 发明,是基于距离向量算法的动态路由协议。 EIGRP(Enhanced Interior Gateway Routing Protocol) 是增强版的 IGRP 协议。它属于动态内部网 关路由协议,仍然使用矢量-距离算法。但它的实现比 IGRP 已经有很大改进,其收敛特性 和操作效率比 IGRP 有显著的提高。它的收敛特性是基于 DUAL ( Distributed Update Algorithm ) 算法的。 DUAL 算法使得路径 在路由计算中根本不可能形成环路。它的收敛时间可以与已存在的其他任何路由协议相匹敌
Enhanced IGRP 与其它路由选择协议之间主要区别包括:收敛宽速( Fast Convergence )、 支持
变长子网掩模( Subnet Mask )、局部更新和多网络层协议。执行 Enhanced IGRP 的路由 器存储
了所有其相邻路由表,以便于它能快速利用各种选择路径( Alternate Routes )。如果没有合适路
径, Enhanced IGRP 查询其邻居以获取所需路径。直到找到合适路径, EnhancedIGRP 查询才会
终止,否则一直持续下去。EIGRP 不作周期性更新。取而代之,当路径度量标准改变时, Enhanced IGRP 只发送局 部更新(Partial Updates )信息。局部更新信息的传输自动受到限制,从而使得只有那些需 要信息的路由器才会更新。基于以上这两种性能,因此 Enhanced IGRP 损耗的带宽比 IGRP 少得多。
3.3 简述域名解析过程,本机如何干预域名解析
参考回答
(1)在浏览器中输入 www.qq.com 域名,操作系统会先检查自己本地的 hosts 文件是否有这个网址 映射关系,如果有,就先调用这个IP 地址映射,完成域名解析。
(2)如果 hosts 里没有这个域名的映射,则查找本地 DNS 解析器缓存,是否有这个网址映射关系,
如果有,直接返回,完成域名解析。
(3)如果 hosts 与本地 DNS 解析器缓存都没有相应的网址映射关系,首先会找 TCP/IP 参数中设置的首选DNS 服务器,在此我们叫它本地 DNS 服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。
(4)如果要查询的域名,不由本地 DNS 服务器区域解析,但该服务器已缓存了此网址映射关系,
则调用这个 IP 地址映射,完成域名解析,此解析不具有权威性。
(5)如果本地 DNS 服务器本地区域文件与缓存解析都失效,则根据本地 DNS 服务器的设置(是否
设置转发器)进行查询,如果 未用转发模式 ,本地 DNS 就把请求发至 13 台根 DNS ,根 DNS 服务器收到请求后会判断这个域名(.com) 是谁来授权管理,并会返回一个负责该顶级域名服务器的一个 IP 。本地DNS 服务器收到 IP 信息后,将会联系负责 .com 域的这台服务器。这台负责 .com 域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com 域的下一级 DNS 服务器地址 (qq.com) 给本地DNS 服务器。当本地 DNS 服务器收到这个地址后,就会找 qq.com 域服务器,重复上面的动作,进行查询,直至找到 www.qq.com 主机。
(6)如果用的是 转发模式 , 此 DNS 服务器就会把请求转发至上一级 DNS 服务器,由上一级服务器
进行解析,上一级服务器如果不能解析,或找根 DNS 或把转请求转至上上级,以此循环 。不管是本
地 DNS 服务器用是是转发,还是根提示,最后都是把结果返回给本地 DNS 服务器,由此 DNS 服务器再返回给客户机。从客户端到本地DNS 服务器是属于递归查询,而 DNS 服务器之间就是的交互查询就是迭代查询。 - 通过修改本机 host 来干预域名解析,例如:
在 /etc/hosts 文件中添加一句话。
192.168.188.1 www.baidu.com
保存文件后再 ping 一下 www.baidu.com 就会连接到 192.168.188.1 了每一行为一条记录,分成两部分,第一部分是IP ,第二部分是域名。 一个 IP 后面可以跟多个域名 ,可以是几十个甚至上百个每一行只能有一个IP ,也就是说一个域名不能对应多个 IP如果有多行中出现相同的域名(对应的ip 不一样),会按最前面的记录来解析。
3.4 简述 DNS 查询服务器的基本流程是什么? DNS 劫持是什么?
参考回答 - 打开浏览器,输入一个域名。比如输入 www.163.com ,这时,你使用的电脑会发出一个 DNS 请求到本地DNS 服务器。本地 DNS 服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动。DNS请求到达本地 DNS 服务器之后,本地 DNS 服务器会首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果。如果没有,本地DNS 服务器还要向 DNS 根服务器进行查询。根DNS 服务器没有记录具体的域名和 IP 地址的对应关系,而是告诉本地 DNS 服务器,你可以到域服务器上去继续查询,并给出域服务器的地址。本地DNS 服务器继续向域服务器发出请求,在这个例子中,请求的对象是 .com 域服务器。 .com 域服务器收到请求之后,也不会直接返回域名和IP 地址的对应关系,而是告诉本地 DNS 服务器,你的域名的解析服务器的地址。最后,本地DNS 服务器向域名的解析服务器发出请求,这时就能收到一个域名和 IP 地址对应关系,本地DNS 服务器不仅要把 IP 地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时,可以直接返回结果,加快网络访问。
- DNS 劫持 就是 通过劫持了 DNS 服务器,通过某些手段取得某域名的解析记录控制权,进而修改此域 名的解析结果,导致对该域名的访问由原 IP 地址转入到修改后的指定 IP ,其结果就是对特定的网址不能访问或访问的是假网址,从而实现窃取资料或者破坏原有正常服务的目的。DNS 劫持通过篡改
DNS服务器上的数据返回给用户一个错误的查询结果来实现的。
DNS 劫持症状:在某些地区的用户在成功连接宽带后,首次打开任何页面都指向 ISP 提供的 " 电信互
联星空 " 、 " 网通黄页广告 " 等内容页面。还有就是曾经出现过用户访问 Google 域名的时候出现了百
度的网站。这些都属于 DNS 劫持。
3.5****简述网关的作用是什么,同一网段的主机如何通信
参考回答
- 网关即网络中的关卡,我们的互联网是一个一个的局域网、城域网、等连接起来的,在连接点上就是一个一个网络的关卡,即我们的网关,他是保证网络互连的,翻译和转换,使得不同的网络体系能够进行。
- 网内通信,即通信双方都位处同一网段中,数据传输无需经过路由器 ( 或三层交换机 ) ,即可由本网段自主完成。假设发送主机的ARP 表中并无目的主机对应的表项,则发送主机会以目的主机 IP 地址为内容,广播ARP请求以期获知目的主机 MAC 地址,并通过交换机 ( 除到达端口之外的所有端口发送,即洪泛(Flooding))向全网段主机转发,而只有目的主机接收到此 ARP 请求后会将自己的 MAC 地址和 IP 地址装入ARP 应答后将其回复给发送主机,发送主机接收到此 ARP 应答后,从中提取目的主机的 MAC 地
址,并在其 ARP 表中建立目的主机的对应表项 (IP 地址到 MAC 地址的映射 ) ,之后即可向目的主机发
送数据,将待发送数据封装成帧,并通过二层设备 ( 如交换机 ) 转发至本网段内的目的主机,自此完
成通信。
3.6 简述 CSRF 攻击的思想以及解决方法
参考回答 - CSRF 全称叫做,跨站请求伪造。就是黑客可以伪造用户的身份去做一些操作,进而满足自身目
的。要完成一次CSRF 攻击,受害者必须依次完成两个步骤:
1 )登录受信任网站 A ,并在本地生成 Cookie。
2 )在不登出 A 的情况下,访问危险网站 B 。
此时,黑客就可以获取你的 cookie 达成不可告人的目的了。 - CSRF 攻击是一种请求伪造的攻击方式,它利用的是服务器不能识别用户的类型从而盗取用户的信息来攻击。因此要防御该种攻击,因为从服务器端着手,增强服务器的识别能力,设计良好的防御机制。主要有以下几种方式:
1 )请求头中的 Referer 验证(不推荐)
HTTP 的头部有一个 Referer 信息的字段,它记录着该次 HTTP 请求的来源地址(即它从哪里来
的) , 既然 CSRF 攻击是伪造请求是从服务器发送过来的,那么我们就禁止跨域访问,在服务器端增
加验证,过滤掉那些不是从本服务器发出的请求,这样可以在一定程度上避免 CSRF 攻击。 但是这
也有缺点,比如如果是从搜索引擎所搜结果调整过来,请求也会被认为是跨域请求。
2 )请求令牌验证( token 验证)
token 验证是一种比较广泛使用的防止 CSRF 攻击 的手段,当用户通过正常渠道访问服务器时,服务器会生成一个随机的字符串保存在session 中,并作为令牌( token )返回给客户端,以隐藏的形式保存在客户端中,客户端每次请求都会带着这个token ,服务器根据该 token 判断该请求是否合法
3.7 说说 MAC 地址和 IP 地址分别有什么作用
参考回答 - IP 地址是 I P 协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻 辑地址,以此来屏蔽物理地址的差异。 而 MAC 地址,指的是物理地址,用来定义网络设备的位置。
- IP 地址的分配是 根据网络的拓扑结构 ,而不是根据谁制造了网络设置。若将高效的路由选择方案建立在设备制造商的基础上而不是网络所处的拓朴位置基础上,这种方案是不可行的。
- 当存在一个附加层的地址寻址时,设备更易于移动和维修。例如,如果一个以太网卡坏了,可以被更换,而无须取得一个新的IP 地址。如果一个 IP 主机从一个网络移到另一个网络,可以给它一个新的IP 地址,而无须换一个新的网卡。
- 无论是局域网,还是广域网中的计算机之间的通信,最终都表现为将数据包从某种形式的链路上的初始节点出发,从一个节点传递到另一个节点,最终传送到目的节点。数据包在这些节点之间的移动都是由ARP ( Address Resolution Protocol :地址解析协议)负责 将 IP 地址映射到 MAC 地址上
来完成的 。
3.8简述TCP****三次握手和四次挥手的过程
参考回答
三次握手
1 )第一次握手:建立连接时,客户端向服务器发送 SYN 包( seq=x ),请求建立连接,等待确认
2 )第二次握手:服务端收到客户端的 SYN 包,回一个 ACK 包( ACK=x+1 )确认收到,同时发送一个 SYN包(seq=y )给客户端
3 )第三次握手:客户端收到 SYN+ACK 包,再回一个 ACK 包( ACK=y+1 )告诉服务端已经收到
4 )三次握手完成,成功建立连接,开始传输数据
四次挥手
1 )客户端发送 FIN 包( FIN=1 )给服务端,告诉它自己的数据已经发送完毕,请求终止连接,此时客户端不发送数据,但还能接收数据
2 )服务端收到 FIN 包,回一个 ACK 包给客户端告诉它已经收到包了,此时还没有断开 socket 连接,而是等待剩下的数据传输完毕
3 )服务端等待数据传输完毕后,向客户端发送 FIN 包,表明可以断开连接
4 )客户端收到后,回一个 ACK 包表明确认收到,等待一段时间,确保服务端不再有数据发过来,然后彻底断开连接
3.9说说TCP 2次握手行不行?为什么要3****次
参考回答
- 为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
- 如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认
3.10简述TCP和UDP****的区别,它们的头部结构是什么样的
参考回答
- TCP 协议是 有连接的 ,有连接的意思是 开始传输实际数据之前 TCP 的客户端和服务器端必须通过三
次握手建立连接,会话结束之后也要结束连接 。而 UDP 是 无连接的
TCP 协议保证数据 按序发送,按序到达,提供超时重传来保证可靠性 ,但是 UDP 不保证按序到达,
甚至不保证到达,只是努力交付,即便是按序发送的序列,也不保证按序送到。
TCP 协议 所需资源多 , TCP 首部需 20 个字节(不算可选项), UDP 首部字段只需 8 个字节。
TCP 有 流量控制和拥塞控制 , UDP 没有,网络拥堵不会影响发送端的发送速率
TCP 是 一对一的连接 ,而 UDP 则可以 支持一对一,多对多,一对多的通信 。
TCP 面向的是 字节流的服务 , UDP 面向的是 报文的服务 。 - TCP 头部结构如下:
cpp
/*TCP头定义,共20个字节*/
typedef struct _TCP_HEADER
{
short m_sSourPort; // 源端口号16bit
short m_sDestPort; // 目的端口号16bit
unsigned int m_uiSequNum; // 序列号32bit
unsigned int m_uiAcknowledgeNum; // 确认号32bit
short m_sHeaderLenAndFlag; // 前4位:TCP头长度;中6位:保留;后6位:标志
位
short m_sWindowSize; // 窗口大小16bit
short m_sCheckSum; // 检验和16bit
short m_surgentPointer; // 紧急数据偏移量16bit
}__attribute__((packed))TCP_HEADER, *PTCP_HEADER;
/*TCP 头中的选项定义
kind(8bit)+Length(8bit ,整个选项的长度,包含前两部分 )+ 内容 ( 如果有的话 )
KIND = 1 表示 无操作 NOP ,无后面的部分
2 表示 maximum segment 后面的 LENGTH 就是 maximum segment 选项的长度(以 byte 为单位,
1+1+ 内容部分长度)
3 表示 windows scale 后面的 LENGTH 就是 windows scale 选项的长度(以 byte 为单位,
1+1+ 内容部分长度)
4 表示 SACK permitted LENGTH 为 2 ,没有内容部分
5 表示这是一个 SACK 包 LENGTH 为 2 ,没有内容部分
8 表示时间戳, LENGTH 为 10 ,含 8 个字节的时间戳
*/
cpp
typedef struct _TCP_OPTIONS
{
char m_ckind;
char m_cLength;
char m_cContext[32];
}__attribute__((packed))TCP_OPTIONS, *PTCP_OPTIONS;
```
UDP头部结构如下:
```cpp
/*UDP头定义,共8个字节*/
typedef struct _UDP_HEADER
{
unsigned short m_usSourPort; // 源端口号16bit
unsigned short m_usDestPort; // 目的端口号16bit
unsigned short m_usLength; // 数据包长度16bit
unsigned short m_usCheckSum; // 校验和16bit
}__attribute__((packed))UDP_HEADER, *PUDP_HEADER;
```
3.11简述TCP****连接 和 关闭的具体步骤
参考回答
- TCP 通过三次握手建立链接
1 )第一次握手:建立连接时,客户端向服务器发送 SYN 包( seq=x ),请求建立连接,等待确认
2 )第二次握手:服务端收到客户端的 SYN 包,回一个 ACK 包(
ACK=x+1 )确认收到,同时发送一个 SYN 包
( seq=y )给客户端
3 )第三次握手:客户端收到 SYN+ACK 包,再回一个 ACK 包(
ACK=y+1 )告诉服务端已经收到
4 )三次握手完成,成功建立连接,开始传输数据
- 通过 4 次挥手关闭链接
1 )客户端发送 FIN 包( FIN=1 )给服务端,告诉它自己的数据已经发送完毕,请求终止连接,此时客户端不发送数据,但还能接收数据
2 )服务端收到 FIN 包,回一个 ACK 包给客户端告诉它已经收到包了,此时还没有断开 socket 连接,而是等待剩下的数据传输完毕
3 )服务端等待数据传输完毕后,向客户端发送 FIN 包,表明可以断开连接
4 )客户端收到后,回一个 ACK 包表明确认收到,等待一段时间,确保服务端不再有数据发过来,然后彻底断开连接
3.12简述TCP****连接 和 关闭的状态转移
参考回答
状态转换如图所示:
上半部分是 TCP 三路握手过程的状态变迁,下半部分是 TCP 四次挥手过程的状态变迁。
- CLOSED :起始点,在超时或者连接关闭时候进入此状态,这并不是一个真正的状态,而是这个状态图的假想起点和终点。
- LISTEN :服务器端等待连接的状态。服务器经过 socket , bind , listen 函数之后进入此状态,开 始监听客户端发过来的连接请求。此称为应用程序被动打开(等到客户端连接请求)。
- SYN_SENT :第一次握手发生阶段,客户端发起连接。客户端调用 connect ,发送 SYN 给服务器端,然后进入 SYN_SENT 状态,等待服务器端确认(三次握手中的第二个报文)。如果服务器端不能连接,则直接进入CLOSED 状态。
- SYN_RCVD :第二次握手发生阶段,跟 3 对应,这里是服务器端接收到了客户端的 SYN ,此时服务器由 LISTEN 进入 SYN_RCVD 状态,同时服务器端回应一个 ACK ,然后再发送一个 SYN 即
SYN+ACK 给客户端。状态图中还描绘了这样一种情况,当客户端在发送 SYN 的同时也收到服务器端的 SYN 请求,即两个同时发起连接请求,那么客户端就会从 SYN_SENT 转换到 SYN_REVD 状态。 - ESTABLISHED :第三次握手发生阶段,客户端接收到服务器端的 ACK 包( ACK , SYN )之后,也会发送一个 ACK 确认包,客户端进入 ESTABLISHED 状态,表明客户端这边已经准备好,但 TCP 需要两端都准备好才可以进行数据传输。服务器端收到客户端的 ACK 之后会从 SYN_RCVD 状态转移到 ESTABLISHED 状态,表明服务器端也准备好进行数据传输了。这样客户端和服务器端都是 * 状态 *
描述
CLOSED
阻塞或关闭状态,表示主机当前没有正在传输或者建立的链接
LISTEN
监听状态,表示服务器做好准备,等待建立传输链接
SYN RECV
收到第一次的传输请求,还未进行确认
SYN SENT
发送完第一个 SYN 报文,等待收到确认
ESTABLISHED
链接正常建立之后进入数据传输阶段
FIN WAIT1
主动发送第一个 FIN 报文之后进入该状态
FIN WAIT2
已经收到第一个 FIN 的确认信号,等待对方发送关闭请求
TIMED WAIT
完成双向链接关闭,等待分组消失
CLOSING
双方同时关闭请求,等待对方确认时
CLOSE WAIT
收到对方的关闭请求并进行确认进入该状态
LAST ACK
等待最后一次确认关闭的报文
ESTABLISHED 状态,就可以进行后面的数据传输了。所以 ESTABLISHED 也可以说是一个数据传送状态。
下面看看 TCP 四次挥手过程的状态变迁。
- FIN_WAIT_1 :第一次挥手。主动关闭的一方(执行主动关闭的一方既可以是客户端,也可以是服务器端,这里以客户端执行主动关闭为例),终止连接时,发送 FIN 给对方,然后等待对方返回ACK 。调用 close() 第一次挥手就进入此状态。
- CLOSE_WAIT :接收到 FIN 之后,被动关闭的一方进入此状态。具体动作是接收到 FIN ,同时发送 ACK。之所以叫 CLOSE_WAIT 可以理解为被动关闭的一方此时正在等待上层应用程序发出关闭连接 指令。TCP 关闭是全双工过程,这里客户端执行了主动关闭,被动方服务器端接收到 FIN 后也需要调用 close 关闭,这个 CLOSE_WAIT 就是处于这个状态,等待发送 FIN ,发送了 FIN 则进入LAST_ACK 状态。
- FIN_WAIT_2 :主动端(这里是客户端)先执行主动关闭发送 FIN ,然后接收到被动方返回的 ACK后进入此状态。
- LAST_ACK :被动方(服务器端)发起关闭请求,由状态 2 进入此状态,具体动作是发送 FIN 给对方,同时在接收到ACK 时进入 CLOSED 状态。
- CLOSING :两边同时发起关闭请求时(即主动方发送 FIN ,等待被动方返回 ACK ,同时被动方也发送了FIN ,主动方接收到了 FIN 之后,发送 ACK 给被动方),主动方会由 FIN_WAIT_1 进入此状态, 等待被动方返回ACK 。
- TIME_WAIT :从状态变迁图会看到,四次挥手操作最后都会经过这样一个状态然后进入 CLOSED 状态。
3.13简述TCP****慢启动
参考回答
- 慢启动 ( Slow Start ),是 传输控制协议( TCP )使用的一种阻塞控制机制 。慢启动也叫做 指数增长期 。慢启动是指 每次 TCP 接收窗口收到确认时都会增长 。增加的大小就是已确认段的数目。这种情况一直保持到要么没有收到一些段,要么窗口大小到达预先定义的阈值。如果发生丢失事件,
TCP 就认为这是网络阻塞,就会采取措施减轻网络拥挤。一旦发生丢失事件或者到达阈值, TCP 就
会进入线性增长阶段。这时,每经过一个 RTT 窗口增长一个段。
3.14说说TCP****如何保证有序
参考回答
主机每次发送数据时, TCP 就给每个数据包 分配一个序列号 并且在一个 特定的时间内等待接收主机
对分配的这个序列号进行确认 ,如果发送主机在一个特定时间内 没有收到接收主机的确认,则发送
主机会重传此数据包 。 接收主机利用序列号对接收的数据进行确认,以便检测对方发送的数据是否
有丢失或者乱序等,接收主机一旦收到已经顺序化的数据,它就将这些数据按正确的顺序重组成数
据流并传递到高层进行处理。
具体步骤如下:
(1)为了保证数据包的可靠传递,发送方必须 把已发送的数据包保留在缓冲区 ;
(2)并为每个已发送的数据包 启动一个超时定时器;
(3)如 在定时器超时之前收到了对方发来的应答信息(可能是对本包的应答,也可以是对本包后
续包的应答),则释放该数据包占用的缓冲区 ;
(4)否则, 重传该数据包,直到收到应答或重传次数超过规定的最大次数为止。
(5)接收方收到数据包后, 先进行 CRC 校验,如果正确则把数据交给上层协议 ,然后给发送方发
送一个累计应答包,表明该数据已收到,如果接收方正好也有数据要发给发送方,应答包也可方在
数据包中捎带过去。
3.15说说TCP****常见的拥塞控制算法有哪些
参考回答
- TCP Tahoe/Reno
最初的实现,包括 慢启动、拥塞避免两个部分 。 基于重传超时( retransmission timeout/RTO )和
重复确认为条件判断是否发生了丢包 。两者的区别在于: Tahoe 算法下如果收到三次重复确认,就
进入快重传立即重发丢失的数据包,同时将慢启动阈值设置为当前拥塞窗口的一半,将拥塞窗口设
置为 1MSS ,进入慢启动状态;而 Reno 算法如果收到三次重复确认,就进入快重传,但不进入慢启
动状态,而是直接将拥塞窗口减半,进入拥塞控制阶段,这称为 " 快恢复 " 。
而 Tahoe 和 Reno 算法在出现 RTO 时的措施一致,都是将拥塞窗口降为 1 个 MSS ,然后进入慢启动阶
段。 - TCP BBR ( Bottleneck Bandwidth and Round-trip propagation time )
BBR 是由 Google 设计,于 2016 年发布的拥塞算法。以往大部分拥塞算法是基于丢包来作为降低传
输速率的信号,而 BBR 则基于模型主动探测。该算法使用网络最近出站数据分组当时的最大带宽和
往返时间来建立网络的显式模型。数据包传输的每个累积或选择性确认用于生成记录在数据包传输
过程和确认返回期间的时间内所传送数据量的采样率。该算法认为随着网络接口控制器逐渐进入千
兆速度时,分组丢失不应该被认为是识别拥塞的主要决定因素,所以基于模型的拥塞控制算法能有
更高的吞吐量和更低的延迟,可以用 BBR 来替代其他流行的拥塞算法,例如 CUBIC 。
3.16简述TCP****超时重传
参考回答
TCP 可靠性中最重要的一个机制是处理数据超时和重传。 TCP 协议要求在发送端每发送一个报文段,就启 动一个定时器并等待确认信息;接收端成功接收新数据后返回确认信息。若在定时器超时前数据未能被确认,TCP 就认为报文段中的数据已丢失或损坏,需要对报文段中的数据重新组织和重传。
3.17说说TCP****可靠性保证
参考回答
TCP 主要提供了 检验和、序列号 / 确认应答、超时重传、最大消息长度、滑动窗口控制等方法实现了可靠 性传输。 检验和通过检验和的方式,接收端可以检测出来数据是否有差错和异常,假如有差错就会直接丢弃TCP 段,重新发送。TCP 在计算检验和时,会在 TCP 首部加上一个 12 字节的伪首部。检验和总共计算 3 部分:TCP 首部、 TCP 数据、 TCP 伪首部
序列号 / 确认应答
这个机制类似于问答的形式。比如在课堂上老师会问你 " 明白了吗? " ,假如你没有隔一段时间没有
回应或者你说不明白,那么老师就会重新讲一遍。其实计算机的确认应答机制也是一样的,发送端
发送信息给接收端,接收端会回应一个包,这个包就是应答包。
上述过程中,只要发送端有一个包传输,接收端没有回应确认包( ACK 包),都会重发。或者接收
端的应答包,发送端没有收到也会重发数据。这就可以保证数据的完整性。
超时重传
超时重传是指发送出去的数据包到接收到确认包之间的时间,如果超过了这个时间会被认为是丢包
了,需要重传。那么我们该如何确认这个时间值呢?
我们知道,一来一回的时间总是差不多的,都会有一个类似于平均值的概念。比如发送一个包到接
收端收到这个包一共是 0.5s ,然后接收端回发一个确认包给发送端也要 0.5s ,这样的两个时间就是
RTT (往返时间)。然后可能由于网络原因的问题,时间会有偏差,称为抖动(方差)。
从上面的介绍来看,超时重传的时间大概是比往返时间 + 抖动值还要稍大的时间。
3.18简述TCP****滑动窗口以及重传机制
参考回答
- 滑动窗口协议是传输层进行流控的一种措施,接收方通过通告发送方自己的窗口大小,从而控制发送方的发送速度,从而达到防止发送方发送速度过快而导致自己被淹没的目的。TCP的滑动窗口解决了端到端的流量控制问题,允许接受方对传输进行限制,直到它拥有足够的缓冲空间来容纳更多的数据。
- TCP 在发送数据时会设置一个计时器,若到计时器超时仍未收到数据确认信息,则会引发相应的超时或基于计时器的重传操作,计时器超时称为重传超时( RTO ) 。另一种方式的重传称为快速重传,通常发生在没有延时的情况下。若TCP 累积确认无法返回新的 ACK ,或者当 ACK 包含的选择确 认信息(SACK )表明出现失序报文时,快速重传会推断出现丢包,需要重传。
3.19****说说滑动窗口过小怎么办
参考回答
- 我们可以假设窗口的大小是 1 ,也是就每次只能发送一个数据,并且发送方只有接受方对这个数据进行确认了以后才能发送下一个数据。如果说窗口过小,那么当传输比较大的数据的时候需要不停的对数据进行确认,这个时候就会造成很大的延迟。
3.20说说如果三次握手时候每次握手信息对方没收到会怎么样,分情况介绍
参考回答
- 如果第一次握手消息丢失,那么请求方不会得到 ack 消息,超时后进行重传
- 如果第二次握手消息丢失,那么请求方不会得到 ack 消息,超时后进行重传
- 如果第三次握手消息丢失,那么 Server 端该 TCP 连接的状态为 SYN_RECV, 并且会根据 TCP 的超时重传机制,会等待3 秒、 6 秒、 12 秒后重新发送 SYN+ACK 包,以便 Client 重新发送 ACK 包。而 Server 重
发 SYN+ACK 包的次数,可以设置 /proc/sys/net/ipv4/tcp_synack_retries 修改,默认值为 5. 如果重
发指定次数之后,仍然未收到 client 的 ACK 应答,那么一段时间后, Server 自动关闭这个连接。
client 一般是通过 connect() 函数来连接服务器的,而 connect() 是在 TCP 的三次握手的第二次握手
完成后就成功返回值。也就是说 client 在接收到 SYN+ACK 包,它的 TCP 连接状态就为 established (已连接),表示该连接已经建立。那么如果 第三次握手中的ACK 包丢失的情况下, Client 向server端发送数据, Server 端将以 RST 包响应,方能感知到 Server 的错误。
3.21简述TCP的TIME_WAIT**,为什么需要有这个状态**
参考回答
- TIME_WAIT 状态也成为 2MSL 等待状态。每个具体 TCP 实现必须选择一个报文段最大生存时间 MSL (Maximum Segment Lifetime ),它是任何报文段被丢弃前在网络内的最长时间。这个时间是有限的,因为TCP 报文段以 IP 数据报在网络内传输,而 IP 数据报则有限制其生存时间的 TTL 字段。对一个具体实现所给定的MSL 值,处理的原则是:当 TCP 执行一个主动关闭,并发回最后一个
ACK ,该连接必须在 TIME_WAIT 状态停留的时间为 2 倍的 MSL 。这样 可让 TCP 再次发送最后 ACK 以防这个ACK 丢失(另一端超时并重发最后的 FIN )。 这种2MSL 等待的另一个结果是这个 TCP 连接在 2MSL 等待期间,定义这个连接的插口(客户的 IP 地 址和端口号,服务器的IP 地址和端口号)不能再被使用。这个连接只能在 2MSL 结束后才能再被使 用。 - 理论上,四个报文都发送完毕,就可以直接进入 CLOSE 状态了,但是可能网络是不可靠的,有可能 最后一个ACK 丢失。所以 TIME_WAIT 状态就是用来重发可能丢失的 ACK 报文。
3.22简述什么是MSL**,为什么客户端连接要等待2MSL的时间才能完****全关闭**
参考回答
- MSL 是 Maximum Segment Lifetime 的英文缩写,可译为 " 最长报文段寿命 " ,它是任何报文在网络 上存在的最长时间,超过这个时间报文将被丢弃。
- 为了保证客户端发送的最后一个 ACK 报文段能够到达服务器。 因为这个 ACK 有可能丢失,从而导致 处在LAST-ACK 状态的服务器收不到对 FIN-ACK 的确认报文。服务器会超时重传这个 FIN-ACK ,接着客户端再重传一次确认,重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。假设客 户端不等待2MSL ,而是在发送完 ACK 之后直接释放关闭, 一但这个 ACK 丢失的话,服务器就无法正 常的进入关闭连接状态。
两个理由:
保证客户端发送的最后一个 ACK 报文段能够到达服务端。
这个 ACK 报文段有可能丢失,使得处于 LAST-ACK 状态的 B 收不到对已发送的 FIN+ACK 报文段的
确认,服务端超时重传 FIN+ACK 报文段,而客户端能在 2MSL 时间内收到这个重传的 FIN+ACK
报文段,接着客户端重传一次确认,重新启动 2MSL 计时器,最后客户端和服务端都进入到
CLOSED 状态,若客户端在 TIME-WAIT 状态不等待一段时间,而是发送完 ACK 报文段后立即释 放连接,则无法收到服务端重传的 FIN+ACK 报文段,所以不会再发送一次确认报文段,则服务
端无法正常进入到 CLOSED 状态。防止" 已失效的连接请求报文段 " 出现在本连接中。 客户端在发送完最后一个ACK 报文段后,再经过 2MSL ,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。
3.23说说什么是SYN flood**,如何防止这类攻击?**
参考回答
- SYN Flood 是当前最流行的 DoS (拒绝服务攻击)与 DDoS( 分布式拒绝服务攻击 ) 的方式之一,这是一种利用TCP 协议缺陷,发送大量伪造的 TCP 连接请求,使被攻击方资源耗尽( CPU 满负荷或内存不足) 的攻击方式 .
- 有以下三种方法预防或响应网络上的 DDoS 攻击:
(1) 从互联网服务提供商 (ISP) 购买服务。
许多互联网服务提供商 (ISP) 提供 DDoS 缓解服务,但是当企业网络受到攻击时,企业需要向互联网
服务提供商 (ISP) 报告事件以开始缓解。这种策略称为 " 清洁管道 " ,在互联网服务提供商 (ISP) 收取服务费用时很受欢迎,但在缓解措施开始之前,通常会导致30 到 60 分钟的网络延迟。
(2) 保留在内部并自己解决。
企业可以使用入侵防御系统 / 防火墙技术和专用于防御 DDoS 攻击的专用硬件来实现内部预防和响应
DDoS 攻击。不幸的是,受影响的流量已经在网络上消耗了宝贵的带宽。这使得该方法最适合在托
管设施中配备设备的企业,在这些企业中,流量是通过交叉连接到达互联网服务提供商 (ISP) ,从而保护流向企业其他部门的下游带宽。
(3) 使用内容分发网络 (CDN) 。
由于 IT 团队可以将基础设施置于内容分发网络 (CDN) 后面,因此这种方法可以最大程度地减少对企
业网络基础设施的攻击。这些网络庞大而多样,如果组织订阅 DNS 和 DDoS 缓解措施,则它们可以
保护电子商务站点以及企业本身。
3.24 说说什么是 TCP 粘包和拆包?
参考回答 - TCP 是个 " 流 " 协议,所谓流,就是没有界限的一串数据。大家可以想想河里的流水,是连成一片
的,其间并没有分界线。 TCP 底层并不了解上层业务数据的具体含义,它会根据 TCP 缓冲区的实际
情况进行包的划分,所以在业务上认为,一个完整的包可能会被 TCP 拆分成多个包进行发送,也有
可能把多个小的包封装成一个大的数据包发送,这就是所谓的 TCP 粘包和拆包问题。
答案解析
假设客户端分别发送了两个数据包 D1 和 D2 给服务端,由于服务端一次读取到的字节数是不确定的,故可
能存在以下 4 种情况。
(1)服务端分两次读取到了两个独立的数据包,分别是 D1 和 D2 ,没有粘包和拆包;
(2)服务端一次接收到了两个数据包, D1 和 D2 粘合在一起,被称为 TCP 粘包;
(3)服务端分两次读取到了两个数据包,第一次读取到了完整的 D1 包和 D2 包的部分内容,第二次读取 到了D2 包的剩余内容,这被称为 TCP 拆包;
(4)服务端分两次读取到了两个数据包,第一次读取到了 D1 包的部分内容 D1_1 ,第二次读取到了 D1 包的剩余内容D1_2 和 D2 包的整包。
如果此时服务端 TCP 接收滑窗非常小,而数据包 D1 和 D2 比较大,很有可能会发生第五种可能,即服务端分多次才能将D1 和 D2 包接收完全,期间发生多次拆包。
3.25说说TCP与UDP在网络协议中的哪一层,他们之间有什么区别?
参考回答
TCP 和 UDP 协议都是 传输层 协议。二者的区别主要有:
- 基于连接vs无连接
TCP 是面向连接的协议。
UDP 是无连接的协议。 UDP 更加适合消息的多播发布,从单个点向多个点传输消息。
- .可靠性
TCP 提供交付保证,传输过程中丢失,将会重发。
UDP 是不可靠的,不提供任何交付保证。(网游和视频的丢包情况)
- 有序性
TCP 保证了消息的有序性,即使到达客户端顺序不同, TCP 也会排序。
UDP 不提供有序性保证。
- 数据边界
TCP 不保存数据边界。
虽然 TCP 也将在收集所有字节之后生成一个完整的消息,但是这些信息在传给传输给接受端之
前将储存在 TCP 缓冲区,以确保更好的使用网络带宽。
UDP 保证。
在 UDP 中,数据包单独发送的,只有当他们到达时,才会再次集成。包有明确的界限来哪些
包已经收到,这意味着在消息发送后,在接收器接口将会有一个读操作,来生成一个完整的消
息。
- 速度
TCP 速度慢
UDP 速度快。应用在在线视频媒体,电视广播和多人在线游戏。 - 发送消耗
TCP 是重量级。
UDP 是轻量级。
因为 UDP 传输的信息中不承担任何间接创造连接,保证交货或秩序的的信息。
这也反映在用于报头大小 - 报头大小
TCP 头大。
一个 TCP 数据包报头的大小是 20 字节。
TCP 报头中包含序列号, ACK 号,数据偏移量,保留,控制位,窗口,紧急指针,可选项,填
充项,校验位,源端口和目的端口。
UDP 头小。
UDP 数据报报头是 8 个字节。
而 UDP 报头只包含长度,源端口号,目的端口,和校验和。 - 拥塞或流控制
TCP 有流量控制。 在任何用户数据可以被发送之前, TCP 需要三数据包来设置一个套接字连接。 TCP 处理的可靠性和拥塞控制。
UDP 不能进行流量控制。 - 应用
由于 TCP 提供可靠交付和有序性的保证,它是最适合需要高可靠并且对传输时间要求不高的应用。
UDP是更适合的应用程序需要快速,高效的传输的应用,如游戏
UDP 是无状态的性质,在服务器端需要对大量客户端产生的少量请求进行应答的应用中是非常有用
的。 在实践中,TCP 被用于金融领域,如 FIX 协议是一种基于 TCP 的协议,而 UDP 是大量使用在游戏和娱乐场所。 - 上层使用的协议
基于 TCP 协议的: Telnet , FTP 以及 SMTP 协议。
基于 UDP 协议的: DHCP 、 DNS 、 SNMP 、 TFTP 、 BOOTP 。
3.26****说说从系统层面上,UDP如何保证尽量可靠?
参考回答
- UDP 仅提供了最基本的数据传输功能,至于传输时连接的建立和断开、传输可靠性的保证这些 UDP统统不关心,而是把这些问题抛给了UDP 上层的应用层程序去处理,自己仅提供传输层协议的最基本功能。
- 最简单的方式是在应用层模仿传输层 TCP 的可靠性传输。下面不考虑拥塞处理,可靠 UDP 的简单设计。
添加 seq/ack 机制,确保数据发送到对端
添加发送和接收缓冲区,主要是用户超时重传。
添加超时重传机制。
3.27说一说TCP的keepalive**,以及和HTTP的keepalive的区****别?**
参考回答
- HTTP Keep-Alive
在 http 早期,每个 http 请求都要求打开一个 tpc socket 连接,并且使用一次之后就断开这个 tcp 连
接。使用 keep-alive 可以改善这种状态,即在一次 TCP 连接中可以持续发送多份数据而不会断开连
接。通过使用 keep-alive 机制,可以减少 tcp 连接建立次数,也意味着可以减少 TIME_WAIT 状态连
接,以此提高性能和提高 httpd 服务器的吞吐率 ( 更少的 tcp 连接意味着更少的系统内核调用 ,socket
的 accept() 和 close() 调用 ) 。但是, keep-alive 并不是免费的午餐 , 长时间的 tcp 连接容易导致系统资源
无效占用。配置不当的 keep-alive ,有时比重复利用连接带来的损失还更大。所以,正确地设置
keep-alive timeout 时间非常重要。 - TCP KEEPALIVE
链接建立之后,如果应用程序或者上层协议一直不发送数据,或者隔很长时间才发送一次数据,当
链接很久没有数据报文传输时如何去确定对方还在线,到底是掉线了还是确实没有数据传输,链接
还需不需要保持,这种情况在 TCP 协议设计中是需要考虑到的。 TCP 协议通过一种巧妙的方式去解
决这个问题,当超过一段时间之后, TCP 自动发送一个数据为空的报文给对方,如果对方回应了这
个报文,说明对方还在线,链接可以继续保持,如果对方没有报文返回,并且重试了多次之后则认
为链接丢失,没有必要保持链接。 - TCP 的 keepalive 机制和 HTTP 的 keep-alive 机制是说的完全不同的两个东西, tcp 的 keepalive 是在
ESTABLISH 状态的时候,双方如何检测连接的可用行。而 http 的 keep-alive 说的是如何避免进行重
复的 TCP 三次握手和四次挥手的环节。
3.28简述TCP协议的延迟ACK****和累计应答
参考回答
- 延迟应答指的是: TCP 在接收到对端的报文后,并不会立即发送 ack ,而是等待一段时间发送 ack ,以便将ack 和要发送的数据一块发送。当然 ack 不能无限延长,否则对端会认为包超时而造成报文重传。linux 采用动态调节算法来确定延时的时间。
- 累计应答指的是:为了保证 顺序性 ,每一个包都有一个 ID (序号),在建立连接的时候,会商定起始的ID 是多少,然后按照 ID 一个个发送。而为了保证不丢包,对应发送的包都要进行应答,但不是一个个应答,而是会应答某个之前的 ID ,该模式称为累计应答
3.29说说TCP****如何加速一个大文件的传输
参考回答
- 建连优化: TCP 在建立连接时,如果丢包,会进入重试,重试时间是 1s 、 2s 、 4s 、 8s 的指数递增 间隔,缩短定时器可以让 TCP 在丢包环境建连时间更快,非常适用于高并发短连接的业务场景。
- 平滑发包:在 RTT 内均匀发包,规避微分时间内的流量突发,尽量避免瞬间拥塞
- 丢包预判:有些网络的丢包是有规律性的,例如每隔一段时间出现一次丢包,例如每次丢包都连续 丢几个等,如果程序能自动发现这个规律(有些不明显),就可以针对性提前多发数据,减少重传
时间、提高有效发包率。 - RTO 探测:若始终收不到 ACK 报文,则需要触发 RTO 定时器。 RTO 定时器一般都时间非常长,会 浪费很多等待时间,而且一旦 RTO , CWND 就会骤降(标准 TCP ),因此利用 Probe 提前与 RTO 去试探,可以规避由于 ACK 报文丢失而导致的速度下降问题。
- 带宽评估:通过单位时间内收到的 ACK 或 SACK 信息可以得知客户端有效接收速率,通过这个速率可以更合理的控制发包速度。
- 带宽争抢:有些场景(例如合租)是大家互相挤占带宽的,假如你和室友各 1Mbps 的速度看电
影,会把 2Mbps 出口占满,而如果一共有 3 个人看,则每人只能分到 1/3 。若此时你的流量流量
达到 2Mbps ,而他俩还都是 1Mbps ,则你至少仍可以分到 2/(2+1+1) * 2Mbps = 1Mbps 的 50%
的带宽,甚至更多,代价就是服务器侧的出口流量加大,增加成本。( TCP 优化的本质就是用带宽换用户体验感。
3.30****服务器怎么判断客户端断开了连接
参考回答
- 检测连接是否丢失的方法大致有两种: keepalive 和 heart-beat
- ( tcp 内部机制)采用 keepalive ,它会先要求此连接一定时间没有活动(一般是几个小时),然后发出数据段,经过多次尝试后(每次尝试之间也有时间间隔),如果仍没有响应,则判断连接中断。可想而知,整个周期需要很长 的时间。
- (应用层实现)一个简单的 heart-beat 实现一般测试连接是否中断采用的时间间隔都比较短,可以 很快的决定连接是否中断 。并且,由于是在应用层实现,因为可以自行决定当判断连接中断后应该采取的行为,而keepalive 在判断连接失败后只会将连接丢弃。
3.31****说说端到端,点到点的区别
参考回答
- 端到端通信是针对传输层来说的,传输层为网络中的主机提供端到端的通信。因为无论 tcp 还是 udp协议,都要负责把上层交付的数据从发送端传输到接收端 ,不论其中间跨越多少节点。只不过 tcp 比较可靠而udp 不可靠而已。所以称之为端到端,也就是从发送端到接收端。
它是一个网络连接,指的是在数据传输之前,在发送端与接收端之间(忽略中间有多少设备)为数
据的传输建立一条链路,链路建立以后,发送端就可以发送数据,知道数据发送完毕,接收端确认
接收成功。 也就是说在数据传输之前,先为数据的传输开辟一条通道,然后在进行传输。从发送端 发出数据到接收端接收完毕,结束。端到端通信建立在点到点通信的基础之上,它是由一段段的点到点通信信道构成的,是比点到点通信更高一级的通信方式,完成应用程序(进程 ) 之间的通信。端到端的优点: 链路建立之后,发送端知道接收端一定能收到,而且经过中间交换设备时不需要进行存储转发,因此传输延迟小。端到端传输的缺点:
(1)直到接收端收到数据为止,发送端的设备一直要参与传输。如果整个传输的延迟很长,那么
对发送端的设备造成很大的浪费。
(2)如果接收设备关机或故障,那么端到端传输不可能实现。 - 点到点通信是针对数据链路层或网络层来说的 ,因为数据链路层只负责直接相连的两个节点之间的通信,一个节点的数据链路层接受ip 层数据并封装之后,就把数据帧从链路上发送到与其相邻的下 一个节点。 点对点是基于MAC 地址和或者 IP 地址,是指一个设备发数据给与该这边直接连接的其他设备,这台设备又在合适的时候将数据传递给与它相连的下一个设备,通过一台一台直接相连的设备把数据传递到接收端。直接相连的节点对等实体的通信叫点到点通信。它只提供一台机器到另一台机器之间的通信,不会涉及到程序或进程的概念。同时点到点通信并不能保证数据传输的可靠性,也不能说明源主机与目的主机之间是哪两个进程在通信。
由物理层、数据链路层和网络层组成的通信子网为网络环境中的主机提供点到点的服务
点到点的优点:
(1)发送端设备送出数据后,它的任务已经完成,不需要参与整个传输过程,这样不会浪费发送
端设备的资源。
(2)即使接收端设备关机或故障,点到点传输也可以采用存储转发技术进行缓冲。
点到点的缺点:点到点传输的缺点是发送端发出数据后,不知道接收端能否收到或何时能收到数据。在一个网络系统的不同分层中,可能用到端到端传输,也可能用到点到点传输。如Internet 网, IP及以下各层采用点到点传输,4 层以上采用端到端传输。