核心要点速览

  • 字节序:主机序(小端 / 大端)→ 网络序(大端),转换函数htons()/ntohs()htonl()/ntohl()
  • TCP 核心问题:粘包 / 半包(流式无边界),解决方案:固定长度、分隔符、消息头 + 消息体(最常用)
  • UDP 特性:无粘包、可能丢包、数据报大小受限,读写用sendto()/recvfrom()
  • 并发模型:多线程 / 多进程(简单低并发)、I/O 多路复用(epoll 核心,高并发)、线程池 / 进程池(平衡开销)
  • 可靠性保障:超时(SO_RCVTIMEO)、心跳(应用层 / TCP keepalive)、重连(指数退避)
  • 序列化:Protobuf/FlatBuffers(高性能)、JSON/XML(可读性)、自定义二进制(紧凑)
  • 安全防护:SYN 洪水(SYN Cookie)、数据加密(SSL/TLS)、限流(防火墙 / 应用层)

一、字节序转换(跨平台通信基础)

  • 主机字节序:CPU 存储数据的方式,分小端(低字节存低地址,主流架构)和大端(低字节存高地址)。
  • 网络字节序:统一为大端(避免跨平台差异),所有网络传输数据需转换为此格式。
  • 核心转换函数
    • 短整型(2 字节):htons()(主机→网络)、ntohs()(网络→主机)
    • 长整型(4 字节):htonl()(主机→网络)、ntohl()(网络→主机)

二、TCP 粘包与半包问题

TCP 是字节流协议(无消息边界),导致接收方无法直接区分完整消息。

1. 问题成因

  • 粘包:Nagle 算法合并小数据包、接收方缓冲区未及时读取,多个消息合并为一个 TCP 报文。
  • 半包:消息超过 MSS(最大报文段长度)被拆分、接收方缓冲区不足,一个消息仅读取部分数据。

2. 解决方案(应用层定义消息边界)

方案类型 核心逻辑 优点 缺点
固定长度消息 约定每个消息长度固定,接收方按固定长度读取 实现简单 灵活性差,消息长度不确定时浪费带宽
分隔符标记 用特殊字符(如\r\n)作为消息结束标记 灵活,无需预设长度 需处理消息内容包含分隔符的情况
消息头 + 消息体 4 字节消息头存储消息体长度,先读头再读体 通用、灵活,无冗余 需额外解析消息头,逻辑稍复杂
  • 最常用:消息头 + 消息体(兼顾灵活性和效率)。

三、UDP 数据报(无连接传输)

1. 核心特性

  • 无连接、无粘包(数据报独立传输)、不可靠(可能丢包、乱序)。
  • 数据报大小受限(通常不超过 MTU,约 1500 字节),超出会被分片或丢弃。

2. 关键读写函数

  • sendto(int sockfd, const void* buf, size_t len, int flags, const struct sockaddr* dest_addr, socklen_t addrlen):指定目标地址发送数据。
  • recvfrom(int sockfd, void* buf, size_t len, int flags, struct sockaddr* src_addr, socklen_t* addrlen):接收数据并获取源地址。

四、并发连接处理(服务器高并发核心)

1. 常见并发模型对比

模型类型 核心原理 优点 缺点 适用场景
多线程 / 多进程(每连接一个) 为每个连接创建独立线程 / 进程处理 实现简单,无共享状态问题 资源开销大,支持并发数有限(几千) 连接数少、逻辑复杂(如数据库连接)
I/O 多路复用(select/poll/epoll) 单线程管理多个连接,仅处理有事件的连接 资源开销低,支持高并发(百万级) 逻辑复杂,需处理非阻塞 I/O Web 服务器、即时通讯等高并发场景
线程池 / 进程池 预先创建固定线程 / 进程,分配连接处理 平衡资源开销与并发能力 线程数固定,极端情况可能瓶颈 中等并发、连接生命周期短的场景

2. epoll 核心优势(Linux 高并发首选)

  • 事件驱动而非轮询:仅通知就绪连接,效率 O (1)(select/poll 为 O (n))。
  • 共享内存:fd 集合存储在内核,避免用户态与内核态频繁拷贝。
  • 支持两种触发模式:
    • 水平触发(LT,默认):缓冲区有数据则持续通知,易用不易漏。
    • 边缘触发(ET):仅数据到来时通知一次,需一次性读完缓冲区,效率更高。

五、连接可靠性保障(避免 “假死” 连接)

1. 超时处理

  • 问题:recv()/send()默认阻塞,连接异常时可能永久阻塞。
  • 解决方案:用setsockopt()设置超时参数(SO_RCVTIMEO接收超时、SO_SNDTIMEO发送超时),或结合epoll_wait()的超时参数。

2. 心跳机制(检测连接存活)

  • 原理:定期发送心跳包,未收到回应则判定连接失效。
  • 实现方式:
    • 应用层心跳:业务协议中加入固定格式心跳包(如每 30 秒发送,5 秒未回应断连)。
    • TCP keepalive:内核层定期发送探测包,默认超时较长(需调整参数)。

3. 断连重连(客户端)

  • 核心策略:指数退避(重连间隔 1s→2s→4s→…→上限 60s),避免频繁重试冲击服务器。
  • 限制:超过最大重试次数后报警(如网络彻底故障)。

六、数据序列化与反序列化(跨平台传输)

核心要求:跨平台兼容、效率、可读性

方案类型 核心特点 优点 缺点 适用场景
自定义二进制格式 手动打包 / 解析,处理大小端 紧凑高效,字节流小 开发复杂,兼容性差 对效率要求极高、协议固定的场景
JSON/XML(文本格式) 文本标记数据结构 可读性好,跨平台性强 冗余大,解析效率低 调试友好、数据量小的场景
Protobuf/FlatBuffers IDL 定义结构,自动生成代码(二进制) 效率高,支持版本兼容 可读性差,需工具解析 高性能场景(游戏、分布式系统)

七、网络安全与攻击防护(面试高频)

1. SYN 洪水攻击

  • 原理:攻击者发送大量SYN报文但不完成三次握手,耗尽服务器半连接队列资源。
  • 防护:开启 SYN Cookie(服务器用 Cookie 验证请求合法性,不维护半连接队列)。

2. 数据传输加密

  • 方案:用 SSL/TLS 协议(如 HTTPS)对传输数据加密,避免明文被窃听或篡改。

3. 端口扫描与限流

  • 防护:防火墙限制异常 IP 连接频率,或应用层实现限流(如单 IP 每秒最多 10 次连接)。