【计算机网络】高频计网面试总结
TCP和UDP的区别
-
tcp:
- 保证数据可靠,(
检验和、序列号去重、确认应答、滑动窗口、超时重传、拥塞控制、流量控制
) - 面向连接的,建立连接需要
三次握手
,断开要四次挥手
- 传输单位是字节流
- 头部20字节****以上,开销大,传输效率较低
- 应用场景:聊天,文件传输,邮件,浏览网页
- 保证数据可靠,(
-
udp:
- 数据不可靠,可能丢包、乱序,但是延迟更低
- 无连接,发送数据不需要建立连接
- 传输单位是数据包
- 头部仅8字节,传输效率高
- 应用场景:直播,语音通信
tcp重可靠性,udp重性能
讲一下tcp的三次握手和四次挥手
- 三次握手:
- 客户端向服务端发送
同步报文
,附带seq=x序列号,SYN=1同步标志位,之后进入SYN_SENT状态 - 服务端收到后,如果同意建立连接,发送
同步确认报文
,同步标志位SYN=1,确认标志位ACK=1附带序列号seq=y,ack=x+1,服务端进入SYN_RCVD - 客户端收到后回复
确认报文
,确认标志位ACK=1,确认号ack=y+1,seq=x+1,进入ESTABLISHED,服务端收到后也进入ESTABLISHED状态
- 客户端向服务端发送
seq 随机序列号,作为自己即将发送数据的编号
SYN 同步标志位,用于建立连接,是一个请求同步序列号
ACK 确认标志位,表示确认前面收到的数据
ack 确认号,告诉对方他下一个发的消息的seq
- 四次挥手:
- 客户端向服务端发送
连接释放报文
,FIN=1,ACK=1,seq=m,ack=n,主动断开连接,等待服务端确认 - 服务端收到报文后发送
确认报文
,ACK=1,seq=n,ack=m+1,这时tcp处于半关闭,客户端到服务端的断开了,但是服务端到客户端的还没断 - 服务端向客户端发送
连接释放报文
,FIN=1,ACK=1,seq=n+1,ack=m+1 - 客户端收到后发出
确认报文
,ACK=1,seq=m+1,ack=n+2,此时,客户端进入TIME_WAIT状态,这个时候客户端的tcp连接还没有释放,必须经过2*MSL(最长报文段寿命)时间后,才进入closed,而服务端只要收到客户端的确认报文
就立即进入closed,可以看到,正常情况
下,服务端结束tcp连接要比客户端早一些
- 客户端向服务端发送
为什么客户端的TIME_WAIT状态必须等待2*MSL?
-
首先讲一下为什么要等一段时间:在非正常情况下,客户端对服务端的
确认报文
不一定会到达服务器(网络波动之类),这时服务器会因为超时重传机制再次发送连接释放报文
,如果客户端不等一段时间,那么就收不到了,也就没办法再次回传确认报文
,服务端就没法断开,造成资源浪费。 -
再就是为什么
客户端要等
2MSL:MSL指的是报文在网络上的最长存活时间,可以理解为从客户端发送到服务端,最长要MSL的时间,也就是说,如果服务端等了MSL却没收到确认报文,那么他会立刻重传,再到达客户端就又是MSL,一共2MSL,这时客户端就可以重新回应,而不是过早关机
此外等这2*MSL可以让客户端在重新建立下一个新连接时,网络中没有存活的旧的该客户端报文,也就是说防止了失效的请求报文的出现
为什么连接建立的时候是三次握手,而断开的时候要四次?
- 断开要四次的关键:是在服务端收到客户端的断开请求之后,此时服务端可能还有一些东西没处理/传输完,所以会先发一个
确认报文
,等传完之后再发连接释放报文
,所以一般服务器的ACK和FIN都会分开发,因此导致断开的时候要四次。
为什么建立连接的时候是三次而不是两次?
- 三次主要是为了避免
历史连接请求
的影响:- 假设只用两次,客户端向服务端发送建立连接请求,但是超时了
- 客户端触发超时重传,这次一下就被服务端收到了,于是服务器直接建立连接
- 但是姗姗来迟的第一次超时的请求报文也发到了服务器,结果服务器又建立了一个连接,但是客户端已经进入ESTABLISHED状态,服务器持续等待,导致
半连接问题
,浪费资源。
- 如果有客户端的最后一次回应,那么只要服务器收到了这次回应,就不会再理会这个客户端的其他连接建立请求了,因为服务端已经明确连接建立了,而不是像只用2次时,服务端不知道客户端的情况,误以为再次收到的请求报文是因为客户端没收到服务器的确认报文,从而再次建立连接
说下TCP首部
- 首部常见字段:
- 端口号:源端口号(16位)指明该报文来自哪里,目标端口号(16位)要传给哪个协议或者应用
- 序列号(32位)seq,接受方用来进行数据的排序
- 确认号(32位)ack,发送方期望接受的接收方的下一个字节编号
- 首部长度(4位)指定tcp首部占用多少个32位字(4byte),帮助定位数据开始位置,因为4位最大能标识15,所以首部最大60byte
- 保留位(6位)
- 标志位(6位)控制连接状态
- URG:标识紧急指针是否有效
- SYN:建立连接消息标志
- ACK:表示确认号是否有效
- FIN:告知连接关闭
- PSH:缓冲区尚未填满
- RST:要求重新建立连接
- 窗口大小(16位)滑动窗口的窗口大小,是缓冲区的大小,告诉发送方,我(接收方)还能接收多少数据(流量控制机制)
- 校验和(16位)用CRC算法校验tcp头和数据
- 紧急指针(32位)只在URG标志位有效时使用
归纳记忆:
端口标识(源端口、目标端口)
数据顺序与确认(序列号、确认号)
控制信息(标志位、首部长度)
性能控制(窗口大小、校验和、紧急指针)
扩展功能(可选字段)
连接TCP建立后,客户端故障的话,服务端是怎么处理的?
- 设置了一个保活计时器,在服务端每次收到客户端消息的时候重置
- 如果计时器到期仍没有收到消息,服务器会每隔75s发送一个探测报文
- 连发10个没反应就关闭tcp连接
TCP如何保证可靠性?
- 校验和:通过CRC算法校验首部和数据
- 序列号:数据排序,去重
- 确认应答:接收到报文后返回确认报文,并指定下一次的期望报文序号
- 滑动窗口:动态调整发送数据的量,提供不同收发速率,接收方通过窗口大小告知发送方当前的接受能力
- 超时重传:发送数据后超过一定时间未收到ACK会触发超时重传,保证数据送达
- 拥塞控制:发送方根据网络,调整发送速率
- 流量控制:接收方结合自身数据处理能力和滑动窗口大小,向发送方协调速率
TCP拥塞控制四大算法:
- 慢开始:发送窗口从1MSS(最大报文段)开始传输,发送方每接收一次ACK就
指数增长
下一次的窗口大小。
但是这样会导致增长到一定程度时,很容易一下超出承担的流量阈值,于是引出拥塞避免 - 拥塞避免:为慢开始的窗口大小设定一个阈值,当超过阈值时,只会
线性增长
+1MSS - 快速重传:应对接收方数据没收到的情况,(如果没有快速重传,会等待保活定时器触发,有等待延迟)为了快速重传,规定:当发送方连续收到三个重复ACK,就会立刻重传
- 快速恢复:发现方察觉丢包后,避免慢开始(从1MSS开始增长),而是将窗口减半,并进入拥塞避免,提高传输的恢复效率
什么是SYN泛洪攻击?如何防范?
- SYN泛洪攻击属于DOS攻击,通过发送大量半连接请求,消耗服务器资源
- 半连接指的是,三次握手中,服务器发送同步确认报文后,进入SYN_RCVD等待客户端的ACK,如果一直没收到,就会重发,浪费资源
- 攻击者通过伪造大量假ip向服务器发送
SYN同步报文
,服务器回复同步确认报文
,但是客户端不响应ACK,就会导致大量半连接占满队列,服务器瘫痪
一般检测到大量随机ip且服务器出现大量SYN_RECV就可以判断是SYN泛洪攻击
防范措施:
- 网络层:
- 防火墙/路由器过滤异常流量
- 限制每个ip的SYN速率
- TCP/IP协议栈优化:
- 增加最大半连接数,提高抗攻击能力
- 缩短SYN超时时间
- 在SYN中嵌入cookies,只有回复正确ACK才响应连接(特点是不需要维护半连接队列,有效抵御SYN泛洪攻击)
浏览器输入URL的执行过程
- DNS域名解析:
- 查找顺序:
- 浏览器缓存
- 操作系统缓存(通过ipconfig /displaydns)
- hosts文件
- 本地DNS服务器(一般由运营商提供)
- 根域名服务器
- 顶级DNS服务器
- 权威DNS服务器
HTTP协议
的话,TCP连接建立(三次握手)如果用HTTPS协议
要进行TLS四次握手,服务器身份验证,以及协商加密和会话密钥来实现后续加密通信- 发送HTTP请求
- 处理请求返回响应html页面
- 浏览器解析html页面
- 加载静态资源(css,javascript,图片等)
- 页面渲染,呈现
https://github.com/0voice