【网络】TCP/UDP总结复盘
1.UDP的格式
2.TCP的格式
3.TCP是来解决什么问题的?
答:
解决IP层的不可靠传输问题,可能数据包丢失、损坏、重复等
为上层应用层提高可靠有序的数据传输服务
通过校验和、确认应答机制、序列号来解决不可靠传输和无序性问题
通过流量控制--->>滑动窗口来解决发送发送方和接受方的消息接受能力问题
通过拥塞控制--->>慢启动/拥塞窗口来解决因网络问题导致大面积丢包的问题
4.TCP和UDP的核心区别?
答:
TCP是面向连接的(需要提前建立连接)、面向字节流的
UDP是无连接的(可以直接发送)、面向数据报的
TCP报头最小20字节,20-60字节
UDP报头固定8字节
TCP有重传机制、可靠性高、有确认应答、超时重传、快重传、序列号、校验和、流量控制、拥塞控制
UDP仅有校验和,可靠性不高,适合延迟低的,实时性高的
5.TCP和UDP的应用场景?
答:
TCP web访问 文件传输 数据库连接 邮件等
UDP 直播 在线游戏如移动位置,对历史位置不感兴趣 DNS 高频交易 局域网广播等
6.UDP头部为什么没有首部长度字段?
答:
UDP报头长度固定8字节,避免复杂结构,固定长度提高效率
7.TCP头部格式?为什么需要TCP协议?
答:
两个16位端口号
16位窗口大小
16位紧急指针
16位校验和
4位首部长度
6个标志位
6个保留位
选项
有效载荷
为什么需要:保证数据传输的可靠性 安全性 又快又稳,解决丢包乱序重复等问题
8.TCP工作在哪一层?
答:
传输层 网络层上面 应用层下面 负责数据的传输
9.服务器监听一个端口,TCP“最大连接数“怎么计算?
答:
理论上无上限、单机主机64K个、每个连接占用一个fd,可能取决fd的上限
每个客户端有约三万个端口、所以单个客户端能发送3万个连接
还取决于内存 因为每个TCP连接都要管理起来
10.TCP的粘包、拆包机制是什么?
答:
TCP是面向字节流的,粘包是指报文之间没有边界,数据都在缓冲区里一块放着,读取是读取定长数据,可能读取半块也可能一块半,简单来说粘包就是多个数据被合并接受
TCP有Nagle算法优化 会新缓存一部分数据再发送,导致粘包,如果对方未及时读取,可能导致数据堆在一起
拆包是对报文拆成多段发送,可能由于报文长度过大,分开发,也可能对方缓冲区小,先发一部分
11.如何解决粘包、拆包?
答:
固定长度协议、在头部添加数据长度、用分隔符分割
12.说说TCP的三次握手?
答:
---》客户端connect发起连接---》发送SYN报文 进入SYN_SENT状态
---》服务器收到SYN报文---》回复SYN+ACK,进入SYN_RCVD状态,连接放入半连接队列
---》客户端收到SYN+ACK---》客户端发送ACK并进入连接状态
---》服务器收到ACK---》从半连接放入全连接队列并进入连接状态
如果SYN丢失,重发,对面无感知
如果SYN+ACK丢失,客户端认为丢包,重发SYN
如果最后的ACK丢失,服务器发送RST给客户端 进行重新连接
13.为什么必须TCP三次握手?
答:
两次的话,对方无法确认是否收到SYN+ACK
四次的话没必要,因为有捎带应答机制
14.什么是半连接队列?作用?
答:
半连接队列相当于缓冲池
如果有大量请求到来,先将一部分放入半连接队列,防止有的连接被丢弃
15.什么是SYN Flood攻击?如何解决?
答:
因为TCP三次握手,有人恶意攻击,频繁发起SYN请求,但是不进行ACK应答
因为服务器必须要接受连接,所以每个SYN请求都会接受,导致半连接队列满了,其他请求进不来了
解决:调整半连接队列容量、超时断开、限速、防火墙
16.为什么需要四次挥手?
答:
为什么不是三次呢?--》被动方可能不想断开,所以需要一来一回
有可能有未处理完的数据传输,确保对方都收到终止信号防止资源泄露
17.除了四次挥手,还有什么办法断开连接?
答:
RST标志位置1,表示重置连接,一端如果一旦收到 RST立即丢弃所有已缓存数据,并进入closed状态,并向应用层返回错误,属于急迫中断,不会等待对方的确认,常用于程序突然关闭,网络突然中断的情况
收到非法报文,无效的序列号
半连接队列超时
连接超时强制断开
18.四次挥手各报文丢失会怎样?
答:
重传,直到应答位置
第一次挥手发送FIN报文并且进入FIN_WAIT1状态,等待对方的ACK响应
如果对面的ACK响应没收到(可能FIN丢失了,对方未收到,也可能对面的ACK丢包了),超过一段时间重传FIN报文,直到收到ACK或者超过重传最大次数(此时连接强制断开)
第二次挥手应答ACK报文
如果收到了FIN,则进入CLOSE_WAIT状态,然后发送ACK给对方,对方收到会进入FIN_WAIT2状态,如果ACK报文丢失,对面会重传FIN,如果收到重复的FIN,还会发送ACK即使处于CLOSE_WAIT状态
第三次挥手FIN丢失
等待关闭的一方完成输出处理后准备关闭了,发送FIN报文给对方,进入LAST_ACK状态等待对方的ACK,若丢失,对面不知道你什么时候准备好关闭,会一直停留在FIN_WAIT2状态
所以如果自己在LAST_WAIT状态超时后,会重传FIN报文,跟对方没关系,对方不知道你什么时候准备好关闭
第四次挥手ACK丢失
收到FIN后进入TIME_WAIT状态(等待2MSL时间,确保对方收到ACK),最终关闭连接,对方收到ACK,进入closed状态
如果丢失,主动方在TIME_WAIT状态在收到重复的FIN会在此发送ACK,如果还是没收到,2MSL后自动关闭
任何一个报文丢失都会通过超时重传的机制来恢复
19.为什么四次挥手需要TIME_WAIT状态?
答:
可能关闭后,还剩余一些报文没有处理在网络中
确保对方收到ACK,等待2MSL(报文最大生存周期,通常2分钟),避免对方没收到ACK,而重发FIN,如果对方真没收到,对方重发FIN,还会发送ACK回去,直到对方收到
如果没有time_wait状态,最后一个ACK丢失了,被动方一直处于LAST_ACK状态,连接无法正常关闭,资源泄露
防止旧报文干扰后续新连接
TCP连接由源Ip 源端口 目的ip 目的端口 四元组标识,当一个连接关闭,新连接可能复用相同的四元组(客户端短时间内重新连接服务器的同一端口号)
如果上一个连接的被丢弃的旧报文还在网络中,此时新连接可能收到这些“垃圾”数据,数据错乱
time_wait等待2MSL保证了一个报文在网络中的存活最大时间到期
总结:确保对方收到ACK、等待旧报文过期,防止干扰新链接
20.CLOSE_WAIT状态持续时间过长的原因?
答:
服务器在close_wait状态,没正常调用关闭接口,比如阻塞住了,会长期占用资源
21.如果客户端在time_wait状态崩溃,会怎样?
答:
服务器没收到ACK,重发FIN报文,一直收不到回应,超时关闭连接,释放资源
22.TIME_WAIT过多有什么危害?如何优化?
答:
导致端口耗尽、内存占用高
为什么产生:用户频繁连接断开连接、产生大量的TIME_WAIT,都在等待2MSL时间,导致这段时间资源耗尽,导致文件描述符不够了
如何优化:使用连接池,减少频繁创建新链接、内核参数优化、缩短MSL时间、设置端口复用(即使处于MSL时间内,新连接仍然可以使用此连接)
关于端口复用的问题:端口复用只能用于四元组不相同,相同也会失败
23.在TIME_WAIT状态收到新SYN会怎样?
答:
丢失此请求、判定为旧连接冲突
因为四元组相同 如果不同的话可以连接,不会冲突
24.已建立连接,客户端突然断电异常崩溃会怎样?
答:
断点不会发送FIN RST ,服务端还会认为正在连接状态,定时发送心跳包探测,收不到应答会重发、到一定次数会关闭连接、也可能因为空闲时长太长发送报文探测,没应答断开
如果进程是突然崩溃的,,操作系统会替代进程进行四次挥手或者RST
25.TCP中何时会出现RST报文?
答:
服务器未开启监听,客户端发起连接,服务器发回RST告知无法连接
连接已关闭但收到数据,一方处于正常关闭状态CLOSED,但收到对方数据(可能是网络延迟的旧数据)会回复RST报文,表示当前连接已失效
半连接队列溢出,可能对新连接发送RST
收到非法报文、不是我的包或者序列号不对
应用程序强制关闭、资源耗尽、强制RST
携带URG位、但是紧急指针无数据 可能RST
26.TCP协议如何保证可靠传输?
答:
序列号去重
校验和 判定报文正确
超时重传
确认应答
滑动窗口
流量控制
拥塞控制
快重传
捎带应答
27.TCP超时重传解决了什么问题?
答:
解决了数据丢包问题
28.有了超时重传为什么还要有快重传
答:
提高效率,超时重传时间长
快重传快速恢复、超时重传会把慢启动窗口置1MSS 快重传增长更快
29.滑动窗口的作用?
答:
为重传(超时重传,快重传)提供底层支持,保存旧数据
实现流量控制 动态调整发送量,避免对方过载,提高效率
结合确认应答 保证可靠性
允许连续发送多个数据,提高效率
30.流量控制和拥塞控制的步骤?
答:
流量控制 避免发送过快 对面接收过慢
在三次握手期间交换互相的窗口大小 (16位窗口大小)
拥塞控制 防止发送过快 大面积丢包
慢启动 拥塞避免 快重传 快恢复
31.半连接队列和全连接队列?
答:
32.TCP keepalive 和 HTTP keepalive的区别?
答:
TCP keepalive 是在传输层定时发送心跳包探测,清理空闲连接
HTTP keepalive 是应用层通过HTTP头部复用同一个TCP连接进行多次请求处理,减少握手开销
33.TCP和UDP可以共用一个端口号吗?
答:
可以,五元组 四元组不同就行
34.如何在UDP实现可靠传输
答:
确认+重传 发送一段时间就停下,启动定时器,收到ACK才继续,超时重传
滑动窗口 允许等待确认前连续发送多个数据
流量控制 拥塞控制
35.SYN报文什么情况会被丢弃?
答:
非监听状态、半连接队列满了、报文非法、防火墙拦截
有时伴随着回复RST
36.TCP的主要缺陷?
答:
连接开销大、拥塞控制过于保守(可能短时间内无法充分发挥带宽,触发重传后置1)、头部阻塞(如果之前数据丢失,需要先把之前数据发送过去才能处理后面的)、小包延迟与Nagle/Ack延迟冲突(Nagle算法是攒一些再发,延迟ACK是等会再发,可能导致阻塞,延迟高)
36.TCP如何优化?
答:
改进握手/挥手 客户端第一次握手后下次连接可在SYN中携带应用数据,服务器收到直接响应
37.讲讲拥塞控制?
答:
简称cwnd
限制可发送数据量
动态调整发送速率 防止网络阻塞 大量丢包
TCP滑动窗口中的发送窗口是 对面可接受窗口大小和拥塞窗口的最小值
核心:慢启动 拥塞避免 快重传 快恢复
慢启动:三次握手后,每收到一个ACK增大一点 前期指数 后期线性 快速探测带宽
拥塞避免:指数增长到阈值改为线性增长
当超时重传或者快重传发生
超时重传:严重拥塞 直接慢启动窗口砍一半 然后重新进入慢启动阶段
快重传:收到3个重复ACK 轻微拥塞 也砍一半 不过进入快速恢复阶段 收到重复ACK线性增长 收到新ACK 回复原大小
优点:动态调整速率 避免丢包
快速恢复
缺点:在高宽带的情况下不好,例如网络宽带超级高 拥塞窗口需要很长时间才能填满带宽 带宽利用率下降
丢包就下调窗口,但是可能丢包不是因为网络问题
慢启动代价高,丢包重传需要重新从1MSS开始
拥塞窗口大小初始一个MSS 增长单位是MSS
38.快重传如何做到的?对面如何提前知道丢包了?
答:
根据序列号!收到一个序列号不是连续的 就知道这个序列号前面的丢了,然后发送 之前收到的序列号的ACK 告诉对方需要从那里重新发
对面通过ACK来确认是否收到,但是如果三次同一的ACK代表需要重传了