You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现Redis克隆时read()函数末尾额外追加FF字节的问题排查

Redis克隆TCP服务器接收请求时出现额外FF字节的问题分析

这不是正常行为,问题根源在于你没有正确处理TCP字节流的边界,加上栈内存未初始化导致的脏数据干扰。以下是具体分析和修复方案:

1. FF字节的真实来源

你用gef查看的0x0000ffff474e4950里,0x474e4950是客户端实际发送的"PING"(小端序显示,字节顺序反转后对应P(0x50)、I(0x49)、N(0x4E)、G(0x47)),而后面的0000ffff是栈内存的脏数据——因为client_request是栈上分配的数组,初始值未被初始化,你只读取了4个字节的请求内容,剩下的内存区域保留着之前的随机值,调试时会被一并显示出来,并非客户端发送的内容。

2. 必须修复的几个问题

  • 添加字符串终止符:TCP是无边界的字节流,read返回的是实际读取的字节数,你需要手动在读取到的字节末尾添加'\0',否则后续字符串处理逻辑(比如extract_command)会越界读取脏数据。
  • 初始化栈数组:声明数组时直接初始化为0,避免脏数据干扰调试和逻辑判断。
  • 修复extract_command的参数问题:当前代码中command是未初始化的野指针,直接传入会导致未定义行为,需要给它分配有效缓冲区(栈上数组或动态内存)。

3. 修改后的代码示例

调整handle_client中的读取逻辑:

ssize_t bytes_read;
char client_request[1024] = {0}; // 初始化数组所有字节为0
char command[64]; // 分配足够大的栈缓冲区存命令

// 留1个字节给终止符,避免缓冲区溢出
bytes_read = read(client_fd, client_request, sizeof(client_request) - 1);
if (bytes_read == -1) {
        printf("Read failed: %s \n", strerror(errno));
        return;
}
client_request[bytes_read] = '\0'; // 手动添加字符串终止符
if (bytes_read < 2) {
        handle_send_usage(client_fd);
        return;
}
extract_command(client_request, command); // 传入有效缓冲区

4. 验证方法

修改后可以用以下方式确认请求内容:

// 只打印实际读取到的字节,避免脏数据干扰
printf("Received request: %.*s\n", (int)bytes_read, client_request);

调试时指定查看前N个字节(比如前4个):

gef➤ x/4bx client_request

就能看到客户端实际发送的0x50 0x49 0x4E 0x47,不会再出现额外的FF字节。

内容的提问来源于stack exchange,提问作者Udeshya D.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 14:39:53