这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记 在抖音服务器项目中,计算机网络是不可缺少的一环,传输层协议更是计算机网络中的重中之重。我将通过两篇文章22个问题带你领略传输层协议的风采。
12.为什么挥手四次后要等待2msl时间?为什么引入time_wait?
- 优雅的关闭 TCP 连接,也就是尽量保证被动关闭的一端收到它自己发出去的 FIN 报文的 ACK 确认报文;
- 处理延迟的重复报文,这主要是为了避免前后两个使用相同四元组的连接中的前一个连接的报文干扰后一个连接。 简单点来说:
- 可靠的实现TCP全双工的终止
- 允许老的重复的TCP数据包在网络中消逝
13.TCP 短连接和长连接的区别
短连接:Client 向 Server 发送消息,Server 回应 Client,然后一次读写就完成了,这时候双方任何一个都可以发起 close 操作,不过一般都是 Client 先发起 close 操作。短连接一般只会在 Client/Server 间传递一次读写操作。
短连接的优点:管理起来比较简单,建立存在的连接都是有用的连接,不需要额外的控制手段。
长连接:Client 与 Server 完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。
在长连接的应用场景下,Client 端一般不会主动关闭它们之间的连接,Client 与 Server 之间的连接如果一直不关闭的话,随着客户端连接越来越多,Server 压力也越来越大,这时候 Server 端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可以避免一些恶意连接导致 Server 端服务受损;如果条件再允许可以以客户端为颗粒度,限制每个客户端的最大长连接数,从而避免某个客户端连累后端的服务。
长连接和短连接的产生在于 Client 和 Server 采取的关闭策略,
减少无效连接操作,这就有了 TCP 的 Keepalive(保活探测)机制。
14.为什么UDP没有粘包问题?
- TCP使用了Nagle算法优化,目的是为了避免发送小的数据包。UDP没有使用Negle算法。
在 Nagle 算法开启的状态下,数据包在以下两个情况会被发送:
如果包长度达到MSS(或含有Fin包),立刻发送,否则等待下一个包到来;如果下一包到来后两个包的总长度超过MSS的话,就会进行拆分发送;
等待超时(一般为200ms),第一个包没到MSS长度,但是又迟迟等不到第二个包的到来,则立即发送。 2. 即使TCP关闭Nagle算法优化,仍然会出现粘包现象。UDP是基于数据报的传输层通信协议。 UDP的首部记录了UDP 数据报文的长度,因此在接收端的应用层能清晰地将不同的数据报文区分开。
TCP首部没有包含长度信息,可根据ip数据包的首部计算出TCP数据包的长度,但是TCP 发送端在发的时候就不保证发的是一个完整的数据报,仅仅看成一连串无结构的字节流,这串字节流在接收端收到时哪怕知道长度也没用,因为它很可能只是某个完整消息的一部分。
15.TCP什么情况下会发生粘包,拆包?
- 要发送的数据大于 TCP 发送缓冲区剩余空间大小,将会发生拆包。
- 待发送数据大于 MSS(最大报文长度),TCP 在传输前将进行拆包。
- 要发送的数据小于 TCP 发送缓冲区的大小,TCP 将多次写入缓冲区的数据一次发送出去,将会发生粘包。
- 接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包。
16.TCP如何解决粘包,拆包问题?
由于 TCP 本身是面向字节流的,无法理解上层的业务数据,所以在底层是无法保证数据包不被拆分和重组的,这个问题只能通过上层的应用协议栈设计来解决,根据业界的主流协议的解决方案,归纳如下:
- 消息定长:发送端将每个数据包封装为固定长度(不够的可以通过补 0 填充),这样接收端每次接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。
- 设置消息边界:服务端从网络流中按消息边界分离出消息内容。在包尾增加回车换行符(标志位)进行分割,例如 FTP 协议。(发送端在发送时还会加入各种校验字段【校验和或者对整段完整数据进行 CRC 之后获得的数据】放在标志位后面,在接收端拿到整段数据后校验下确保它就是发送端发来的完整数据。)
- 将消息分为消息头和消息体:消息头中包含表示消息总长度(或者消息体长度)的字段。
17.TCP是如何保证可靠性的?
- 建⽴连接(标志位):通信前确认通信实体存在。
- 序号机制(序号、确认号):确保了数据是按序、完整到达。
- 主机每次发送数据时,TCP就给每个数据包分配一个序列号并且在一个特定的时间内等待接收主机对分配的这个序列号进行确认,
- 如果发送主机在一个特定时间内没有收到接收主机的确认,则发送主机会重传此数据包。
- 接收主机利用序列号对接收的数据进行确认,以便检测对方发送的数据是否有丢失或者乱序等,
- 接收主机一旦收到已经顺序化的数据,它就将这些数据按正确的顺序重组成数据流并传递到高层进行处理。
- 数据校验(校验和): CRC校验全部数据。
- 超时重传(定时器):保证因链路故障未能到达数据能够被多次重发。
- 窗⼝机制(窗⼝):提供流量控制,避免过量发送。
- 拥塞控制:同上。
18.TCP的窗口机制
窗口是缓存的一部分,用来暂时存放字节流。发送方和接收方各有一个窗口,接收方通过 TCP 报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其它信息设置自己的窗口大小。 发送窗口内的字节都允许被发送,接收窗口内的字节都允许被接收。如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态;接收窗口的滑动类似,接收窗口左部字节已经发送确认并交付主机,就向右滑动接收窗口。
接收窗口只会对窗口内最后一个按序到达的字节进行确认,例如接收窗口已经收到的字节为 {31, 34, 35},其中 {31} 按序到达,而 {34, 35} 就不是,因此只对字节 31 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收。
19.TCP流量控制
流量控制是为了控制发送方发送速率,保证接收方来得及接收。
接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。
实际上,为了避免此问题的产生,发送端主机会时不时的发送一个叫做窗口探测的数据段,此数据段仅包含一个字节来获取最新的窗口大小信息。
20.TCP流量控制和拥塞控制的区别
流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。
- 流量控制属于通信双⽅协商;拥塞控制涉及通信链路全局。
- 流量控制需要通信双⽅各维护⼀个发送窗、⼀个接收窗,对任意⼀⽅,接收窗⼤⼩由⾃身决定,发送窗⼤⼩由接收⽅响应的TCP报⽂段中窗⼝值确定;拥塞控制的拥塞窗⼝⼤⼩变化由试探性发送⼀定数据量数据探查⽹络状况后⽽⾃适应调整。
- 实际最终发送窗⼝ = min{流控发送窗⼝,拥塞窗⼝}。
21.提高网络利用率?
-
Nagle 算法 发送端即使还有应该发送的数据,但如果这部分数据很少的话,则进行延迟发送的一种处理机制。具体来说,就是仅在下列任意一种条件下才能发送数据。如果两个条件都不满足,那么暂时等待一段时间以后再进行数据发送。
- 已发送的数据都已经收到确认应答。
- 可以发送最大段长度的数据时。
-
延迟确认应答 接收方收到数据之后可以并不立即返回确认应答,而是延迟一段时间的机制。
-
捎带应答
在一个 TCP 包中既发送数据又发送确认应答的一种机制,由此,网络利用率会提高,计算机的负荷也会减轻,但是这种应答必须等到应用处理完数据并将作为回执的数据返回为止。
22. 键入网址到网页显示,期间发生了什么?
- 浏览器解析 URL 并生成 HTTP 消息
get post 以及响应报文的知识
- 查询服务器域名对应的 IP 地址
域名解析的工作流程?
- 客户端首先会发出一个 DNS 请求,并发给本地 DNS 服务器(也就是客户端的 TCP/IP 设置中填写的 DNS 服务器地址)。
- 本地域名服务器收到客户端的请求后,如果缓存里的表格能找到 www.baidu.com,则它直接返回 IP 地址。如果没有,本地 DNS 会去问它的根域名服务器:根域名服务器是最高层次的,它不直接用于域名解析,但能指明一条道路。
- 根 DNS 收到来自本地 DNS 的请求后,发现后置是 .com,说:“www.baidu.com 这个域名归 .com 区域管理”,我给你 .com 顶级域名服务器地址给你,你去问问它吧。”
- 本地 DNS 收到顶级域名服务器的地址后,发起请求问“老二, 你能告诉我 www.baidu.com 的 IP 地址吗?”
- 顶级域名服务器说:“我给你负责 www.baidu.com 区域的权威 DNS 服务器的地址,你去问它应该能问到”。
- 本地 DNS 于是转向问权威 DNS 服务器:“老三,www.baidu.com对应的IP是啥呀?” server.com 的权威 DNS 服务器,它是域名解析结果的原出处。为啥叫权威呢?就是我的域名我做主。
- 权威 DNS 服务器查询后将对应的 IP 地址 X.X.X.X 告诉本地 DNS。
- 本地 DNS 再将 IP 地址返回客户端,客户端和目标建立连接。