banner
Bai

Bai

写代码菜的一批 🤣
twitter
telegram
tg_channel
pixiv
github
bilibili
whatsapp

TCP/IP协议十五问

一、什么是网络层?#

TCP 网络分层一般分为四层,当然也有说法是五层

  1. 应用层(HTTP):封装数据包
  2. 传输层(TCP):增加 TCP 头部,包含端口号等信息
  3. 网络层(IP):增加 IP 头部,包含 IP 地址等信息
  4. 网络接口层(ARP):增加以太网头部,包含 MAC 地址等信息

网络分层的优点:

  • 各层独立:限制了依赖关系的范围,各层之间使用标准化的接口,各层不需要知道上下层是如何工作的,增加或者修改一个应用层协议不会影响传输层协议;
  • 灵活性:比如路由器不需要应用层和传输层,分层以后路由器就可以只用加载更少的几个协议层
  • 易于测试和维护:提高了可测试性,可以独立的测试特定层,某一层有了更好的实现可以整体替换掉;
  • 能促进标准化:各层职能清晰,方便标准化;

二、TCP 的三次握手?为什么不是两次或者四次?#

  1. 客户端向服务端发送 SYN,seq = x;
  2. 服务端向客户端发送 SYN,seq = y, ACK = x+1;
  3. 客户端向服务端发送 ACK = y+1;

两次不行因为如果只做两次无法确定服务端的接收能力;
两次握手后建立连接,有可能导致由于时延产生的多次连接建立,导致资源浪费;
四次的话没必要,会导致资源浪费。

三、TCP 的四次挥手?为什么不能是三次?#

  1. 客户端向服务端发送 FIN,seq = x+2,ACK = y+1;
  2. 服务端向客户端发送 ACK = x+3;
  3. 服务端发送完剩余数据后,再向客户端发送 FIN,seq = y+1;
  4. 客户端向服务端发送 ACK = y+2;

三次不行,会导致服务端的 ACK 和 FIN 将延迟发送,如果延迟时间过长,客户端将再次重发断开请求,导致资源浪费。

四、为什么 SYN/FIN 不包含数据却要消耗一个序列号?#

凡是需要对端确认的,一定消耗 TCP 报文的序列号;

五、什么是半连接队列?什么是 SYN Flood 攻击?#

客户端大量伪造 IP 发送 SYN 包,服务端回复的 ACK+SYN 去到了一个(未知)的 IP 地址,势必会造成服务端大量的连接处于 SYN_RCVD 状态,而服务器的半连接队列大小也是有限的,如果半连接队列满,也会出现无法处理正常请求的情况。

六、TCP 快速打开的原理?#

TCP 快速打开(TCP Fast Open,TFO)
TFO 是在原来 TCP 协议上的扩展协议,它的主要原理就在发送第一个 SYN 包的时候就开始传数据了,不过他要求当前客户端之前已经完成过正常的三次握手。

快速打开分为两个阶段:请求 Fast Open Cookie 和 真正开始 TCP Fast Open

TCP Fast Open 的优势
可以利用握手去除一个往返的 RTT 和防止 SYN-Flood 之类的攻击

七、TCP 报文中的时间戳有什么用?#

TCP Timestamps Option 由四部分构成:类别、长度、发送方时间戳、回显时间戳

第一用于计算 RTT,第二防止序列号的回绕问题,即使使用的序列号相同,也可以通过时间戳来对不同的包进行区分。

八、TCP 的超时重传时间是如何计算的?#

超时重传时间:Retransmission TimeOut, 简称 RTO

经典解决方法
适用于 RTT 较小的情况,SRTT (smoothed round trip time)。
利用最新一次的 RTT 对 SRTT 时间进行更新
SRTT = α × SRTT + (1-α)× RTT

九、TCP 流量控制?#

把发送的数据放到发送缓冲区,把接收的数据放到接收缓冲区。通过实际接收缓冲区的大小,控制发送端的发送。
接收端会告知客户端自己接收窗口,也就是接收缓冲区中空闲的部分。

发送端的数据包的状态:

  • 已发送且已确认
  • 已发送未确认的
  • 未发送但接收端可以接受的(接收端有空间接受)
  • 未发送且不可以发送(接收端没空间接收)

发送端速度较慢:存在大量待发送的字节;
发送端速度较快:存在大量待确认的字节;

十、TCP 的 keep-alive 原理?#

定时发送探测包来探测连接的对端是否存活,但是 keepalive 默认设置的时间过长,7200s 没有实际意义,一般在应用层做心跳机制。

那什么是心跳机制?
定时向服务端发送消息,能响应服务端的消息

长链接业务场景

  • 游戏
  • 即时通讯
    在没有心跳包机制的情况下,网络若掉线,对方不可知;
    如果客户端掉线,服务端不知道,还维持链接,就是额外的无效系统开销。

为什么需要心跳包:

  • 在 NAT、防火墙网络中装设备,保存信道记录;
  • 及时发现对方网络断开,以便及时采取措施;

如何实现心跳包

  • TCP 层面的心跳包,只能够验证网络链接是否异常;
  • 应用层层面的心跳包,验证服务接口是否异常;

为什么不采用 TCP 层面?
应用层的连接如果成功,那么 TCP 所在的传输层必定成功。

十一、TCP 中的端口号?#

  • 源端口:本地端口
  • 目标端口:服务器端口
    最大 65536 个,所以是 0-65535

以下是一些常见的端口号:

  • 21:FTP(文件传输协议)端口,用于文件上传和下载。
  • 22:SSH(安全外壳协议)端口,用于安全远程登录和执行命令。
  • 25:SMTP(简单邮件传输协议)端口,用于电子邮件传输。
  • 80:HTTP(超文本传输协议)端口,用于 Web 浏览器访问网站。
  • 110:POP3(邮局协议版本 3)端口,用于电子邮件客户端接收邮件。
  • 143:IMAP(互联网消息访问协议)端口,用于电子邮件客户端接收邮件。
  • 443:HTTPS(超文本传输安全协议)端口,用于安全的 Web 浏览器访问网站。
  • 3306:MySQL 数据库端口,用于数据存储和检索。
  • 3389:Microsoft 远程桌面端口,用于远程管理和控制计算机。
    这只是一小部分常用的端口号,实际上有许多其他端口号可以用于各种不同的通信协议和应用程序。

十二、TCP 场景问题#

问题 1
AB 两个主机之间建立了一个 TCP 连接,A 主机发给 B 主机两个 TCP 报文,大小分别是 500 和 300,第一个报文的序列号是 200,那么 B 主机接收两个报文后,返回的确认号是多少?
500+300+200 = 1000

问题 2
收到 IP 数据包解析后,如何知道应该投递到上层中的哪个协议(是 TCP 还是 UDP)?
IP 报文头中有协议字段,TCP6,UDP17

问题 3
TCP 提供了一种字节流服务,而收发双方都不保持记录的边界,应用程序应该如何提供他们自己的记录标识呢?

应用程序使用自己约定的规则来标识消息的边界,比如有一些使用回车+换行(“\r\n”),比如 Redis 的通信协议;

十三、TCP 和 UDP 的区别?#

TCP 是一个面向连接的、可靠的、基于字节流的传输层协议;
UDP 是一个面向无连接的传输层协议;

  • 面向连接:指的是客户端和服务端的连接,在通信前通过三次握手建立连接;

  • 可靠性:

  1. TCP 有状态:TCP 会精准记录那些数据发送了,哪些数据已被接收,那些数据未被接收,并且保证数据包按序到达,不允许差错;
  2. TCP 可控制:如果遇到丢包或者网络不佳,TCP 会根据具体情况自行调整,控制自己的发送速度或者重发。

十四、Telnet 和 netstat 的用法#

  • 检查远端端口是否打开,其语法:telnet [ip] [port]
  • 主要用于查询网络情况,如: netstat -ano

十五、Tcpdump 和 wireshark#

用于抓包,例如可以查看三次握手和四次挥手等

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。