Skip to content
Gains Summary
Main Navigation 首页 / Home
C++ 编程 / C++ Programming
系统与高性能 / Systems & Performance
Web 开发 / Web Development
人工智能 / Artificial Intelligence
工业软件 / Industrial Software
其他内容 / Other Topics
C++ 编程 / C++系统与性能 / SystemsWeb 开发 / Web人工智能 / AI工业软件 / Industrial

外观

Sidebar Navigation

← C++ 编程 / C++ Programming

系统与网络编程 / Systems & Networking

1. 系统与网络编程路线 / Systems and Network Programming Roadmap

2. 进程、fork/exec、wait 与信号 / Processes, fork/exec, wait, and Signals

3. 文件描述符、I/O、mmap 与资源所有权 / File Descriptors, I/O, mmap, and Resource Ownership

4. IPC、调度与虚拟内存边界 / IPC, Scheduling, and Virtual Memory Boundaries

5. Socket API、TCP 与连接模型 / Socket API, TCP, and Connection Model

6. 非阻塞 I/O、epoll 与 Reactor / Nonblocking I/O, epoll, and Reactor

7. 协议分帧、HTTP 基础与服务加固 / Protocol Framing, HTTP Basics, and Service Hardening

8. 系统网络调试与生产检查表 / System and Network Debugging and Production Checklist

本页目录

Socket API、TCP 与连接模型 / Socket API, TCP, and Connection Model ​

1. 为什么要先系统理解 TCP 和 socket ​

很多 C++ 网络学习一上来就写 socket()、bind()、listen()、accept(),但没有解释这些调用分别改变了哪一个内核对象的状态。结果是:代码能跑 echo,却不知道为什么 recv 会读到半条消息,为什么端口被占用,为什么服务端有两个 socket,为什么关闭后还有 TIME_WAIT。

本篇先建立最基础的网络模型,再进入 C++ 代码。你应该把 socket 看成“应用程序拿在手里的网络资源句柄”,把 TCP 看成“内核维护的可靠字节流协议状态机”。

text
application code
  |
  v
socket fd / SOCKET handle
  |
  v
kernel TCP stack
  |
  v
IP packets on network
1
2
3
4
5
6
7
8
9
10

2. 一句话心智模型 ​

TCP 是可靠、有序、面向连接的字节流;socket 是进程访问这条字节流的内核句柄;应用协议必须自己定义消息边界。

text
client process                         server process
  socket fd                               listening socket fd
      |                                       |
      | connect                               | bind + listen
      |-------------------------------------->|
      |            TCP handshake              |
      |<--------------------------------------|
      |                                       | accept
  connected socket fd                  connected socket fd
      |<========== ordered bytes ==========>|
1
2
3
4
5
6
7
8
9
10

3. 基础词小注释 ​

IP 地址:网络层地址,用来定位一台主机或一个网络接口。TCP 不直接认识域名,域名通常先通过 DNS 解析成 IP。

port:端口是传输层里的服务入口编号。同一台机器可以有多个进程监听不同端口,例如 80、443、5432。

五元组:一条 TCP 连接通常由 source IP、source port、destination IP、destination port、protocol 唯一标识。

socket:应用程序持有的内核网络端点句柄。它不是 TCP 本身,而是用户态访问网络栈的接口。

listening socket:服务端用于监听连接请求的 socket。它不直接承载业务数据,accept 后得到的 connected socket 才读写数据。

connected socket:一次已建立连接对应的 socket。它有对端地址、收发缓冲区和 TCP 状态。

byte stream:字节流表示 TCP 只保证字节有序可靠到达,不保留应用层 message 边界。

backlog:listen 队列相关参数。它不是“最大客户端数”,而是影响等待 accept 的连接队列容量。

half-close:半关闭。TCP 可以关闭写方向但继续读对端数据,常由 shutdown(SHUT_WR) 表示。

TIME_WAIT:主动关闭方常进入的状态,用来处理迟到报文和保证旧连接不会污染新连接。

Nagle:TCP 小包合并算法。它可能降低小包数量,也可能增加交互式延迟。

keepalive:内核级空闲连接探测机制,不等同于应用层心跳,也不能替代业务超时。

4. 网络分层:TCP 在哪一层 ​

实际工程里不需要死背 OSI 七层,但要知道每层负责什么,否则错误会归因错位。

text
application protocol: HTTP, Redis, MySQL, custom framing
transport layer      : TCP or UDP
network layer        : IP routing
link layer           : Ethernet/Wi-Fi

C++ code mainly touches application protocol + socket API.
TCP details live mostly in kernel, but their behavior shapes your code.
1
2
3
4
5
6
7

TCP 不知道你发的是 HTTP 头、JSON、protobuf 还是图片。TCP 只看字节。应用层说“这一段字节是一条请求”,必须靠 HTTP 规则、长度前缀、分隔符或自定义解析器完成。

5. socket 到底是什么 ​

socket 不是连接本身,也不是文件。它是一个被进程持有的内核对象引用。在 POSIX 下它表现为 file descriptor,所以能被 read/write/close/poll/epoll 操作;在 Windows 下是 SOCKET,不能完全等同普通文件句柄。

一个服务端通常至少有两类 socket:

  • listening socket:由 socket -> bind -> listen 创建,用来等待新连接;
  • connected socket:由 accept 返回,用来和某一个客户端读写。
text
server
  listen_fd  : only accept new connections
  conn_fd #1 : read/write client A
  conn_fd #2 : read/write client B
  conn_fd #3 : read/write client C
1
2
3
4
5

把这两类 socket 混起来,是新手最常见错误之一。你不能对 listening socket 读业务数据;你也不应该对 connected socket 再 listen。

6. 地址、端口和五元组 ​

服务端监听的是本地地址和端口,例如 0.0.0.0:8080 或 127.0.0.1:8080。客户端连接时,内核会给客户端选择一个临时端口。连接建立后,五元组标识一条 TCP 连接。

text
client 192.168.1.10:53218
       -> server 192.168.1.20:8080
protocol TCP

5-tuple = (192.168.1.10, 53218, 192.168.1.20, 8080, TCP)
1
2
3
4
5

bind 失败常见原因包括端口被占用、权限不足、地址不存在、TIME_WAIT 相关策略不当。SO_REUSEADDR 能解决一部分重启问题,但不是“强行抢端口”的万能钥匙。

7. 服务端生命周期 ​

最小 TCP 服务端不是一个函数调用,而是一条状态线:

text
socket(AF_INET, SOCK_STREAM)
  -> setsockopt(optional)
  -> bind(local address)
  -> listen(backlog)
  -> loop:
       accept() -> connected fd
       recv()/send() or read()/write()
       close connected fd
  -> close listening fd
1
2
3
4
5
6
7
8
9

每一步都可能失败。工程代码要在错误消息里记录阶段、地址、端口和 errno。否则日志里只有 failed,排查时就只能猜。

8. 客户端生命周期 ​

客户端看起来更短,但也有状态:

text
resolve domain(optional)
  -> socket()
  -> connect(remote address)
  -> send request bytes
  -> recv response bytes until protocol says complete
  -> shutdown/close
1
2
3
4
5
6

connect 成功只说明 TCP 连接建立,不说明应用层协议可用。连接到 HTTP 服务后还要发送合法 HTTP 请求;连接到自定义服务后还要遵守自定义分帧规则。

9. TCP 连接建立:三次握手 ​

三次握手的细节由内核处理,应用层通常看不到每个报文,但它解释了为什么连接不是“发一个包就能通信”。

text
client                         server
  SYN ------------------------>
      <-------------------- SYN + ACK
  ACK ------------------------>

connect returns on client after establishment
accept returns on server when a connection is ready to hand to user space
1
2
3
4
5
6
7

握手也解释了 SYN backlog、accept queue、半开连接和连接洪泛防护为什么存在。listen(backlog) 影响队列行为,但真实上限还受内核参数影响。

10. TCP 是字节流,不是消息流 ​

这是网络编程最重要的一句话。假设客户端执行:

cpp
send(fd, "hello", 5, 0);
send(fd, "world", 5, 0);
1
2

服务端可能看到:

text
recv -> "helloworld"
recv -> "hel"
recv -> "loworld"
recv -> "hello" then "world"
1
2
3
4

这些都可能正确。TCP 只保证字节顺序,不保证 send 和 recv 次数对应。所谓“粘包/半包”不是 TCP 出错,而是应用层误以为 TCP 有消息边界。

11. recv 和 send 的真实语义 ​

recv 返回正数表示读到一些字节,返回 0 表示对端已经有序关闭写方向,返回 -1 表示错误或暂时不可读。

send 返回正数表示内核接收了这些字节进入发送缓冲,不表示对端应用已经处理。它也可能只发送一部分,尤其在非阻塞 socket 或发送缓冲紧张时。

text
while buffer not empty:
  n = send(fd, remaining)
  if n > 0: advance
  if n == -1 and errno == EAGAIN: wait writable
  if n == -1 and fatal: close connection
1
2
3
4
5

12. 最小阻塞 echo 服务 ​

下面代码是教学样例,重点是流程,不是生产封装。真实项目要补 RAII、日志、信号处理、超时和跨平台差异。

cpp
#include <arpa/inet.h>
#include <cerrno>
#include <cstring>
#include <iostream>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>

int main() {
    int listen_fd = ::socket(AF_INET, SOCK_STREAM, 0);
    if (listen_fd < 0) return 1;

    int yes = 1;
    ::setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

    sockaddr_in addr{};
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(8080);

    if (::bind(listen_fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) return 1;
    if (::listen(listen_fd, 128) < 0) return 1;

    for (;;) {
        int conn = ::accept(listen_fd, nullptr, nullptr);
        if (conn < 0) continue;

        char buf[4096];
        for (;;) {
            ssize_t n = ::recv(conn, buf, sizeof(buf), 0);
            if (n > 0) {
                ssize_t written = 0;
                while (written < n) {
                    ssize_t m = ::send(conn, buf + written, n - written, 0);
                    if (m <= 0) break;
                    written += m;
                }
            } else {
                break;
            }
        }
        ::close(conn);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

这个服务一次只处理一个连接。它适合学习 socket 生命周期,但不适合生产。一个客户端长时间不发数据,就会阻塞整个服务。下一篇会讨论非阻塞 I/O 和 epoll。

13. 关闭连接:FIN、RST 与 half-close ​

close(fd) 会释放本进程持有的 socket 引用,并通常触发 TCP 关闭流程。shutdown(fd, SHUT_WR) 只关闭写方向,表示“我不再发送,但还愿意接收”。

text
normal close:
  application done writing
  -> FIN
  -> peer recv returns 0 after buffered bytes consumed

abortive close / reset:
  connection error or SO_LINGER special setting
  -> RST
  -> peer often sees ECONNRESET
1
2
3
4
5
6
7
8
9

TIME_WAIT 通常出现在主动关闭方。它不是 bug,而是 TCP 为了处理迟到报文和旧连接残留设计的状态。服务重启遇到端口占用时,要先判断到底是进程仍在监听,还是 TIME_WAIT 策略问题。

14. 阻塞、超时和取消 ​

阻塞 socket 的优点是直观,缺点是每个调用点都可能让线程停住。accept、connect、recv、send 都可能等待。

生产程序不能只依赖“用户会正常关闭”。至少要有:

  • 连接空闲超时;
  • 读取请求头超时;
  • 请求体大小限制;
  • 写响应超时;
  • 服务关闭时停止 accept,并排空已有连接。

15. 调试工具 ​

bash
ss -lntp           # 查看监听 TCP 端口
ss -antp           # 查看连接状态
lsof -i :8080      # 查看哪个进程占用端口
strace -e trace=network ./server
tcpdump -i lo port 8080 -nn -X
1
2
3
4
5

工具输出要和程序日志对上:connection id、peer address、fd、状态和错误码都应能关联。

16. 常见错误 ​

  • 对 listening socket 读写业务数据。
  • 假设一次 send 对应一次 recv。
  • 忽略 send 部分写。
  • 把 recv 返回 0 当成错误,而不是对端有序关闭。
  • 忘记处理 SIGPIPE 或 EPIPE。
  • 没有设置超时,导致慢客户端占住线程。
  • 日志不记录 peer address 和 errno。

17. 练习 ​

  1. 写一个阻塞 echo 服务,用 nc 127.0.0.1 8080 测试。
  2. 客户端把 hello 拆成两次发送,服务端打印每次 recv 的长度。
  3. 主动关闭客户端,观察服务端 recv 返回值。
  4. 用 ss 观察连接从 ESTABLISHED 到 TIME_WAIT 的变化。
  5. 给 echo 服务加入最大连接时长和最大输入长度。

18. 总结 ​

TCP/socket 基础的关键不是背函数表,而是知道每个函数改变了哪个内核对象状态。服务端有 listening socket 和 connected socket;TCP 是字节流;关闭有方向;错误码是协议现场的一部分。理解这些,后面的 epoll、Reactor、HTTP 解析才不会悬空。

深化切片 1:最小实验 ​

围绕 socket 和 TCP byte stream 设计一个小实验。把一个复杂网络现象拆成一个客户端、一个服务端和一条可重复命令。先确认基础行为,再加并发、超时和异常输入。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 2:抓包观察 ​

围绕 TCP byte stream 和 listen 设计一个小实验。用 tcpdump 或 Wireshark 保存原始报文,确认看到的是 SYN、ACK、FIN、RST、payload 还是应用层解析错误。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 3:错误路径 ​

围绕 listen 和 accept 设计一个小实验。每个系统调用都要处理 EINTR、EAGAIN、ECONNRESET、ETIMEDOUT、EPIPE 等错误,并保留上下文。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 4:资源上限 ​

围绕 accept 和 recv 设计一个小实验。连接数、fd 数、缓冲区、请求大小、队列长度和超时都是协议设计的一部分。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 5:关闭顺序 ​

围绕 recv 和 send 设计一个小实验。网络程序要区分停止接收新连接、排空已有连接、发送剩余响应、关闭写方向、释放 fd。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 6:跨平台 ​

围绕 send 和 close 设计一个小实验。Linux 的 epoll、BSD/macOS 的 kqueue、Windows 的 IOCP 模型不同,C++ 抽象应隐藏平台差异但暴露语义差异。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 7:生产诊断 ​

围绕 close 和 socket 设计一个小实验。日志要包含 connection id、peer address、状态、读写字节数、错误码和关闭原因。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 8:安全边界 ​

围绕 socket 和 TCP byte stream 设计一个小实验。任何来自网络的长度、头字段、路径、编码和压缩数据都不可信,必须先限制再分配。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 9:最小实验 ​

围绕 TCP byte stream 和 listen 设计一个小实验。把一个复杂网络现象拆成一个客户端、一个服务端和一条可重复命令。先确认基础行为,再加并发、超时和异常输入。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 10:抓包观察 ​

围绕 listen 和 accept 设计一个小实验。用 tcpdump 或 Wireshark 保存原始报文,确认看到的是 SYN、ACK、FIN、RST、payload 还是应用层解析错误。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 11:错误路径 ​

围绕 accept 和 recv 设计一个小实验。每个系统调用都要处理 EINTR、EAGAIN、ECONNRESET、ETIMEDOUT、EPIPE 等错误,并保留上下文。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 12:资源上限 ​

围绕 recv 和 send 设计一个小实验。连接数、fd 数、缓冲区、请求大小、队列长度和超时都是协议设计的一部分。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 13:关闭顺序 ​

围绕 send 和 close 设计一个小实验。网络程序要区分停止接收新连接、排空已有连接、发送剩余响应、关闭写方向、释放 fd。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 14:跨平台 ​

围绕 close 和 socket 设计一个小实验。Linux 的 epoll、BSD/macOS 的 kqueue、Windows 的 IOCP 模型不同,C++ 抽象应隐藏平台差异但暴露语义差异。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 15:生产诊断 ​

围绕 socket 和 TCP byte stream 设计一个小实验。日志要包含 connection id、peer address、状态、读写字节数、错误码和关闭原因。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 16:安全边界 ​

围绕 TCP byte stream 和 listen 设计一个小实验。任何来自网络的长度、头字段、路径、编码和压缩数据都不可信,必须先限制再分配。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 17:最小实验 ​

围绕 listen 和 accept 设计一个小实验。把一个复杂网络现象拆成一个客户端、一个服务端和一条可重复命令。先确认基础行为,再加并发、超时和异常输入。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 18:抓包观察 ​

围绕 accept 和 recv 设计一个小实验。用 tcpdump 或 Wireshark 保存原始报文,确认看到的是 SYN、ACK、FIN、RST、payload 还是应用层解析错误。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 19:错误路径 ​

围绕 recv 和 send 设计一个小实验。每个系统调用都要处理 EINTR、EAGAIN、ECONNRESET、ETIMEDOUT、EPIPE 等错误,并保留上下文。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 20:资源上限 ​

围绕 send 和 close 设计一个小实验。连接数、fd 数、缓冲区、请求大小、队列长度和超时都是协议设计的一部分。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 21:关闭顺序 ​

围绕 close 和 socket 设计一个小实验。网络程序要区分停止接收新连接、排空已有连接、发送剩余响应、关闭写方向、释放 fd。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 22:跨平台 ​

围绕 socket 和 TCP byte stream 设计一个小实验。Linux 的 epoll、BSD/macOS 的 kqueue、Windows 的 IOCP 模型不同,C++ 抽象应隐藏平台差异但暴露语义差异。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 23:生产诊断 ​

围绕 TCP byte stream 和 listen 设计一个小实验。日志要包含 connection id、peer address、状态、读写字节数、错误码和关闭原因。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

深化切片 24:安全边界 ​

围绕 listen 和 accept 设计一个小实验。任何来自网络的长度、头字段、路径、编码和压缩数据都不可信,必须先限制再分配。

text
one variable
  -> one observation
  -> one failure mode
  -> one engineering rule
1
2
3
4

复盘时要回答:这个结论属于 TCP 语义、socket API 语义、操作系统实现、应用协议,还是你自己写的 C++ 封装?如果分不清,Socket API、TCP 与连接模型 就还没有真正掌握。

最后更新于:

Pager
上一篇4. IPC、调度与虚拟内存边界 / IPC, Scheduling, and Virtual Memory Boundaries
下一篇6. 非阻塞 I/O、epoll 与 Reactor / Nonblocking I/O, epoll, and Reactor

持续记录,持续成长

Copyright © Tidenflow