一、基础概念
TCP 与 UDP 是活跃于 运输层 的数据传输协议
TCP:传输控制协议
(Transmission Control Protocol)–提供面向连接的,可靠的数据传输服务。具体来说就是一种要建立双端连接才能发送数据,能确保传输可靠的通讯协议。安全性比 UDP 好,但传的没 UDP 快。
UDP:用户数据协议
(User Datagram Protocol)–提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。总结一下就是一种不需要连接,直接朝着目标发,收没收到它不管的协议。可靠性没 TCP 好,但传的比 TCP 快。
二、TCP 的三次握手与四次挥手
2.1 概念:
三次握手和四次挥手其实就是 TCP 协议连接的开始与结束需要进行的步骤。
2.2 流程图
参数定义
- LISTEN:等待从任何远端TCP 和端口的连接请求。 SYN_SENT:发送完一个连接请求后等待一个匹配的连接请求。
- SYN_RECEIVED:发送连接请求并且接收到匹配的连接请求以后等待连接请求确认。
- ESTABLISHED:表示一个打开的连接,接收到的数据可以被投递给用户。连接的数据传输阶段的正常状态。
- FIN_WAIT_1:等待远端 TCP 的连接终止请求,或者等待之前发送的连接终止请求的确认。
- FIN_WAIT_2:等待远端 TCP 的连接终止请求。
- CLOSE_WAIT:等待本地用户的连接终止请求。
- CLOSING:等待远端TCP 的连接终止请求确认。
- LAST_ACK:等待先前发送给远端TCP 的连接终止请求的确认(包括它字节的连接终止请求的确认)
- TIME_WAIT:等待足够的时间过去以确保远端TCP 接收到它的连接终止请求的确认。 TIME_WAIT 两个存在的理由:
1.可靠的实现tcp全双工连接的终止;
2.允许老的重复分节在网络中消逝。 - CLOSED:不在连接状态(这是为方便描述假想的状态,实际不存在)
2.3 三次握手:
过程:
- 一次握手:客户端发送带有 SYN =1 的数据包到服务端 。服务端接收数据包。连接进入服务端的半连接队列
- 二次握手:服务端发送带有 SYN/ACK (SYN为新值,ACK 为
SYN值+1)标志的数据包到客户端 - 三次握手:客户端发送带有带有 ACK (ACK 为 SYN值+1)标志的数据包到服务端。连接进入服务端的全连接队列
题目
(1)为什么要三次握手呢?
是为了确保双方的发送和接受都是正常的。
- 第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常。
- 第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常
- 第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常。
(2)为什么要传回 SYN?
为了告诉发送端,我接收到的信息确实就是你所发送的信号了。
(3)为啥还要传 ACK?
接收方到发送方的通道还需要 ACK 信号来进行验证
(4)两次握手会导致什么问题
二次成功但没有三次握手:服务端没法确认自己的发送和对方的接收正常。
二次失败:客户端和服务端都会发起重传
(5)三次握手会导致什么问题
发送失败,得不到服务端的回应,就会发现连接失败。客户端会重置状态,重传报文。
假如数据未发送,到时间限制后,客户端会检查连接状态,发现检查失败,那状态重置,将连接从半连接状态中移除
(6)Syn 洪泛攻击
概念:属于 dos 攻击的一种。
原理:当连接进入服务端的半连接队列时,服务端需要发送 ACK 确认给对应的客户端,等到客户端返回确认后,才能将连接从半连接队列中移除。但半连接队列是有容纳上限的。假如攻击者不断发起一次握手,并丢掉二次握手发回的 ACK 包,让半连接队列的容纳达到上限。服务端就会拒绝掉一切请求,直到半连接队列空出来。这就会导致正常的请求无法执行。
解决方案:使用syn cookie解决,服务器在第二次握手时不会为第一次握手的SYN创建半开连接,而是生成一个cookie一起发送给客户端,只有客户端在第三次握手发送ACK报文并且验证cookie成功服务器才会创建TCP连接,分配资源。
(7)全连接队列的进入情况
- 全连接队列未满:将连接的相关信息从半连接队列中取出,放入全连接队列。之后服务端accept()处理此请求。
- 当全连接已满且 tcp_abort_on_overflow = 0,server会扔掉client 发过来的ack。之后隔一段时间server会重发握手第二步的syn+ack包给client,如果客户端连接一直排队不上等待超时则会报超时异常。
- 全连接已满且tcp_abort_on_overflow = 1时,server会发送一个reset包给client,表示废除这个握手过程和这个连接(客户端会报connection reset by peer异常)
2.4 四次挥手
过程:
- 一次挥手:客户端发送一个FIN为1,序列号随机生成的报文给服务器(假设序列号为M),进入FIN_WAIT_1状态;
- 二次挥手:服务器收到这个报文之后,发送一个ACK为1,acknowledge number=M+1的应答报文给客户端,进入CLOSE_WAIT状态。此时客户端已经没有要发送的数据了,但仍可以接受服务器发来的数据。
- 三次挥手:服务器关闭与客户端的连接,发送一个FIN为1,序列号随机生成的报文给客户端(假设序列号为N),进入LAST_ACK状态;
- 四次挥手:客户端收到服务器的FIN报文后,进入TIME_WAIT状态;接着发送一个ACK为1,acknowledge number=N+1给服务器;服务器收到后,确认acknowledge number是否为N+1,变为CLOSED状态,不再向客户端发送数据。客户端等待2*MSL(报文段最长寿命)时间后,也进入CLOSED状态。完成四次挥手。
题目:
(1)为什么要四次挥手呢
任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。
(2)为何要等待 2MSL(最大报文生存时间)
因为客户端给服务器发送的ACK报文可能会丢失,TIME_WAIT状态就是用来重发可能丢失的ACK报文。如果服务器没有收到ACK报文,就会重发FIN,如果客户端在2*MSL的时间内收到了FIN,就会重新发送ACK并再次等待2MSL,防止服务器没有收到ACK而不断重发FIN。2MSL 代表报文正常来回的最长时间,超过了就代表接收发生异常了。
(3)为什么不能把服务器发送的ACK和FIN合并起来,变成三次挥手
因为服务器收到客户端的FIN报文时有可能还没有做好断开连接的准备(如还有部分数据没有发给客户端,还在继续发送),但需要先发送一个ACK报文告诉客户端我收到了断开连接的请求,等服务器准备好了,再发一个FIN报文给客户端,告诉客户端可以断开连接了。
(4)什么情况下四次挥手可以变为三次
服务器收到客户端的FIN报文时,已经准备好了断开连接(没有数据要发送了)+开启了捎带应答,就可以讲ACK报文和FIN报文合并发送,变为三次挥手
(5)什么是捎带应答机制
当发送没有携带数据的 ACK,它的网络效率也是很低的,为了提高网络效率, TCP产生了延迟确认策略。
当有响应数据要发送时,ACK 会随着响应数据一起立刻发送给对方
当没有响应数据要发送时,ACK 将会延迟一段时间,以等待是否有响应数据可以一起发送
如果在延迟等待发送 ACK 期间,对方的第二个数据报文又到达了,这时就会立刻发送 ACK
三、TCP 可靠传输的实现方法
3.1 分割排序
应用数据被分割成 TCP 认为最适合发送的数据块。TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
3.2 校验和
TCP 会计算它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
3.3 流量控制与拥塞控制
(1)概念
流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。
TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
拥塞控制:流量控制是发送和接受的缓冲区滑动窗口。拥塞控制是发送与接收间的网络的滑动窗口。用于防止过多的数据注入到网络中,网络中的路由器或链路不致过载。
发送方要维持一个 拥塞窗口(cwnd) 的状态变量。窗口的大小取决于网络的拥塞程度,并且动态变化。发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。
(2)拥塞控制算法
- 慢开始:由小到大逐渐增大拥塞窗口数值。每经过一个传播轮次,cwnd加倍。
- 拥塞避免:每经过一个往返时间RTT就把发送放的cwnd加1。
- 快重传:接收机接受到一个乱序(如越过 M3 的 M4)的数据段时,会直接返回一个重复的确认(M2)。接收机接受到 M5 时也返回一个 M2 的确认,且这个确认不必等待发送数据时一起发送。发送方累计收到三个重复的 ACK 时不必等待重传计时器,直接开始重传。
- 快恢复:快重传时,把(慢开始进行到现在的值)值减半,执行拥塞避免算法
- Reno:在上限值 ssthresh 前执行慢开始,之后执行拥塞避免。当快重传被触发表明拥塞发生后,执行快恢复。
3.4 ARQ协议
(1)简述
自动重传请求(Automatic Repeat-reQuest,ARQ)是OSI模型中数据链路层和传输层的错误纠正协议之一。通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。具体可细分为 停止等待ARQ协议 和 连续ARQ协议
(2)异常处理方案
超时:有一个超时计时器,超过时间则重传
确认丢失:当确认消息在传输过程丢失,接受端在重新接受到后。接受端会丢弃这个重复的M1消息,不向上层交付,并向A发送确认消息
确认迟到:当发送端未接受确认接受信息,重传后收到了两份接受信息,包括之前未接受到的。发送端就会丢弃重复的接收信息,接收端也丢弃重复的信息。
(3)停止等待ARQ协议
概念
每发完一个分组就停止发送,等待对方确认(回复ACK)。若接收方收到重复分组,就丢弃该分组,但同时还要发送确认。
优点:
实现简单
缺点:
信道利用率低,等待时间长
(4)连续ARQ协议
概念
发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累计确认,对按序到达的最后一个分组发送确认
优点:
信道利用率高,容易实现,即使确认丢失,也不必重传
缺点:
不能向发送方反映出接收方已经正确收到的所有分组的信息
四、DNS 协议
4.1 概念
DNS 协议(域名解析协议)是一个应用层协议,功能就是将人类可读的域名 (如,www.qq.com) 转换为机器可读的 IP 地址 (如,119.147.15.13)。
DNS协议默认通过 UDP 协议进行通讯,但是由于广域网中不适合传输过大的 UDP 数据包,因此规定当报文长度超过了 512 字节时,应转换为使用 TCP 协议进行数据传输。
所以,DNS 协议是少有的既可以用 UDP 协议,又可以用 TCP 协议作为底层协议的应用层协议。
4.2 缓存过程
- 浏览器缓存:浏览器会先检查是否在缓存中(浏览器会缓存之前拿到的DNS 2-30分钟时间),没有则调用系统库函数进行查询。
- 操作系统缓存:操作系统也有自己的 DNS 缓存,但在这之前,会先检查域名是否存在于本地的 Hosts 文件里,没有则向 DNS 服务器发送查询请求。
- 路由器缓存:将请求发给路由器,查找ISP服务商缓存的DNS的服务器,如果查找到IP则直接返回,没有的话继续查找。
- ISP 缓存:ISP 就是在客户端电脑上设置的首选 DNS 服务器,它们在大多数情况下都会有缓存。
- 根域名服务器查询:在前面所有步骤都没有缓存的情况下,本地 DNS 服务器会将请求转发到互联网上的根域
4.3 类型
- A 记录:Address:指定对应的IP,所有域名解析同一个 IP
- MX 记录:Mall Exchage:邮件服务器执行自己的 Mall Server,Web 请求仍可得到 A 记录的 IP
- CNAME 记录:Canonical Name:别名解析,为一个域名设置多个别名,更换 IP 时比较方便,但影响性能
- NS 记录:Name Server:指定 DNS 服务器进行域名解析
五、经典题目
5.1 TCP,UDP 协议的区别
- UDP 在传送数据之前不需要先建立连接,远地主机在收到 UDP 报文后,不需要给出任何确认
- UDP 不提供可靠交付,但在某些情况下 UDP 确是一种最有效的工作方式(一般用于即时通信)
- TCP 提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接
- TCP 不提供广播或多播服务。
- TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。
为什么及时通信要用 UDP
TCP 有三次握手机制还有 ARQ 协议等确保可靠性,但这导致 TCP 传输速度很慢,会有延迟,UDP 就不会有,在即时通信领域,这个延迟是不可接受的。