一、应用层自定义协议与序列化
1. 理解 TCP 协议
在使用 read、write 接口时,数据并非直接写入网络。它们是将用户缓冲区的内容拷贝到内核的 TCP 发送缓冲区中,write 函数执行完毕仅代表数据已到达内核缓冲区。
TCP/IP 协议属于操作系统的一部分。TCP 协议维护发送缓冲区和接收缓冲区。发送端将数据拷贝到内核缓冲区后,由 TCP 协议自主控制何时发送、发送多少以及处理错误。
每台主机上都有 TCP 协议,通信本质是两个进程间的数据传输。数据从发送端的 TCP 发送缓冲区通过网络拷贝到对端的接收缓冲区,最终被上层用户读取。TCP 支持全双工是因为它拥有一对发送和接收缓冲区,通过文件描述符即可实现双向通信。
发送端将数据拷贝到内核缓冲区的过程类似于生产者 - 消费者模型,即用户与内核之间的同步交互。当发送缓冲区写满时,write 会阻塞;当接收缓冲区无数据时,read 会阻塞。
TCP 协议不关心写入数据的语义(如 ls -a -l),只关注字节数量。如果对端接收缓冲区空间不足,TCP 协议仅发送可用空间大小的数据,剩余部分暂存。这种情况称为数据粘包问题。TCP 是面向字节流的,是否读完整数据由用户自行控制维护。

2. 序列化与反序列化
若需通过网络发送结构体数据(如包含两个运算数及结果的整数),要求对端拥有相同的结构体定义。直接发送结构体对象面临内存对齐、大小端转换及跨语言兼容等问题。
因此,应用层通常采用序列化与反序列化。
例如,发送消息时除了数据本身还包含时间等信息,可将多个字段合并为一条字符串(以空格分隔)发送给对端,对端按指定分割符提取。将多个字符串合并成一条字符串的过程称为序列化,对端按指定格式提取的过程称为反序列化。

序列化的优势:
- 方便网络发送:将多段数据合并为单段传输。
- 可扩展性和可维护性:新增字段(如日期)只需增加对应字节。
- 方便上层处理:接收方按固定格式解析即可。
3. TCP 接口
TCP 协议是面向字节流的,读取数据可使用 read 或 recv 函数。
recv(sockfd, buf, len, flags) 参数说明:
sockfd:文件描述符。buf:用户自定义缓冲区。len:缓冲区大小。flags:标志位,0 代表阻塞,MSG_DONTWAIT代表非阻塞。
返回值:成功返回读取字节数,失败返回 -1 并设置错误码,返回 0 代表读到文件末尾。
send(sockfd, buf, len, flags) 参数说明:
sockfd:文件描述符。














