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