服务器无法识别客户端消息问题求助(附代码与运行日志)
问题排查与修复方案
核心问题分析
1. 客户端消息携带换行符
客户端通过fgets读取用户输入时,会将输入末尾的换行符\n一并存入缓冲区,发送给服务器后,实际收到的内容是AUTOTEST\n、CLOSE\n,与代码中用于匹配的字符串常量"AUTOTEST"、"CLOSE"(无换行符)不匹配,导致strcmp判断失败,服务器无法识别指令。
服务器日志中收到"AUTOTEST"后直接换行打印、收到"CLOSE"后出现乱码"ST",就是换行符+缓冲区残留旧数据共同导致的。
2. 服务器缓冲区未清空
服务器每次调用read前未清空缓冲区,当新接收的消息长度小于缓冲区原有数据长度时,旧数据残留会干扰后续字符串比较。
3. 客户端参数变量未初始化
客户端main函数中int x;未初始化就进入while(x < argc)循环,触发未定义行为,可能导致参数解析错误。
4. 服务器分支日志缺失
处理"AUTOTEST"指令时,服务器发送响应后未打印日志,无法直观判断分支是否执行。
修复代码
客户端修复
- 去除输入换行符:用
strcspn将fgets读取到的换行符替换为字符串结束符 - 初始化参数变量:将
int x;改为int x = 0;
修改后的客户端消息循环:
while (1) { char input[100]; printf("%s: Sending a request ", argv[0]); fgets(input, sizeof(input), stdin); // 移除换行符 input[strcspn(input, "\n")] = '\0'; printf("%s: Waiting for response...\n", argv[0]); SendRequest(sockfd, input); char buffer[256] = {0}; int valread = read(sockfd, buffer, 256); if (valread < 0) { FatalError(argv[0], "Error receiving response from server"); exit(EXIT_FAILURE); } printf("%s: Received response: %s\n", argv[0], buffer); }
服务器修复
- 每次读取前清空缓冲区:用
memset重置缓冲区 - 完善AUTOTEST分支日志:添加响应发送日志
- 优化消息打印格式:统一添加换行符避免输出混乱
修改后的服务器消息处理循环:
char buffer[256] = {0}; int valread = 0; while ((valread = read(new_socket, buffer, 256)) > 0) { printf("%s: Received message: %s\n", argv[0], buffer); if (strcmp(buffer, "CLOSE") == 0) { break; } else if (strcmp(buffer, "AUTOTEST") == 0) { AutoTest(); const char *response = "Autotest completed"; send(new_socket, response, strlen(response), 0); printf("%s: Sending response: %s\n", argv[0], response); } else { const char *response = "OK."; send(new_socket, response, strlen(response), 0); printf("%s: Sending response: %s\n", argv[0], response); } // 清空缓冲区准备下一次读取 memset(buffer, 0, sizeof(buffer)); }
修复效果验证
- 服务器能正确识别"AUTOTEST"和"CLOSE"指令,执行对应逻辑
- AUTOTEST分支会输出"tested"并返回"Autotest completed"响应
- CLOSE指令会触发服务器关闭连接并退出,日志无乱码
内容的提问来源于stack exchange,提问作者user20602600
相关产品推荐
相关产品推荐

