网络编程:八股文

一.Reactor网络模型

复制代码
+-------------------+
|   应用主线程      |
+-------------------+
          |
          v
+-------------------+
|   Reactor         |
| (事件分发器)      |
+-------------------+
          |
          v
+-------------------+
|  事件多路分发器   |  <--- epoll/poll/select
+-------------------+
          |
          v
+-------------------+
|  事件处理器       |  <--- Handler/Callback
+-------------------+
1.背景

事件处理模型

2,网络处理

将对IO的处理转换为事件的处理
用户层并不知道IO什么时候就绪

3.网络模型构成

非阻塞IO:

当IO未就绪,IO函数立刻返回

操作IO
IO多路复用:

检测多路IO是否就绪

4.工作流程

注册事件:

accept_____listenfd

读事件

connect_____connectfd

写事件

read____clientfd

读事件

write____clinetfd

写事件

被动断开连接

clientfd

读/写事件

read = 0

write = -1 &&errno = EPIPE
处理事件 :

事件触发后说明IO就绪了,处理对应的IO

5.封装流程

封装事件分发器(如 EpollReactor 类)

封装事件处理器(如 Handler/Callback)

提供注册、注销、事件循环等接口

二.reactor和proactor的区别

1. 事件处理时机不同

Reactor 模型

内核检测到事件(如可读、可写)后,通知应用程序 ,应用程序主动进行后续操作(如 read/write),即应用程序负责实际的 I/O 操作
Proactor 模型

应用程序发起异步 I/O 请求后,内核完成实际的 I/O 操作,操作完成后再通知应用程序,应用程序只负责处理结果。

2. 工作流程对比

Reactor 流程

注册事件和回调

内核检测到事件(如可读)

通知应用程序

应用程序执行 read/write
Proactor 流程

应用程序发起异步 I/O 请求

内核异步执行 I/O 操作

I/O 完成后,内核通知应用程序

应用程序处理结果

三.TCP三次握手为什么不是两次

1. 两次握手存在的问题

历史连接请求重传导致误连接

假设客户端第一次发送的 SYN 报文因为网络延迟等原因滞留在网络中,服务端并未收到。客户端重发 SYN 并建立连接,之后关闭。此时,滞留的 SYN 报文又到达服务端,服务端以为是新的连接请求,回复 SYN+ACK,并建立连接。但此时客户端可能已经关闭,导致服务端产生"半连接"或"无效连接"。

2. 三次握手的过程

第一次握手:客户端发送 SYN 报文,表示请求建立连接。

第二次握手:服务端收到 SYN,回复 SYN+ACK,表示收到请求并同意建立连接。

第三次握手:客户端收到 SYN+ACK,回复 ACK,表示自己也准备好了,连接建立。

3. 三次握手的作用
  • 确认双方的接收和发送能力都正常
    • 第一次握手:客户端能发,服务端能收。
    • 第二次握手:服务端能发,客户端能收。
    • 第三次握手:客户端再次确认自己能收,服务端能发。
  • 防止历史连接请求造成误连接
    通过第三次握手,客户端确认服务端的 SYN+ACK 是自己刚刚发起请求后收到的,而不是历史报文,避免误连接。

四.在 Linux 系统中,收发网络包的流程

1. 网络包接收流程

网卡接收数据包

网络包从物理网络到达网卡。
驱动程序处理

网卡驱动将数据包从硬件搬运到内核空间(通常是内核缓冲区)。
协议栈处理

内核网络协议栈(如以太网、IP、TCP/UDP)逐层解析数据包。
数据包分发

根据协议类型和端口,将数据包分发到对应的 socket 缓冲区。
应用层读取

应用程序通过 recvread 等系统调用,从 socket 读取数据。

2.网络包发送流程

应用层写入

应用程序通过 sendwrite 等系统调用,将数据写入 socket。
协议栈封装

内核协议栈将数据封装成 TCP/UDP、IP、以太网帧等格式。
驱动程序发送

数据包从内核缓冲区传递给网卡驱动。
网卡发送

网卡将数据包发送到物理网络。

3.UDP和TCP的区别

TCP 可靠但慢,适合要求数据完整性的场景。

UDP 快但不可靠,适合实时性要求高的场景。

五.TCP是如何保证可靠性的

三次握手建立连接

确保通信双方收发能力正常。
数据包编号(序列号)

每个数据包有序列号,保证数据按序到达。
确认应答(ACK)

接收方收到数据后发送确认,未收到确认的数据会重传。
超时重传

发送方在超时时间内未收到 ACK,会自动重发数据包。
校验和

每个 TCP 段都带有校验和,接收方可检测数据是否损坏。
流量控制

通过滑动窗口机制,防止发送方发送过快导致接收方处理不过来。
拥塞控制

动态调整发送速率,避免网络拥塞。
四次挥手可靠断开连接

确保双方数据都已传输完毕后再断开连接。