为何sendto函数仅在Linux环境返回Bad File descriptor错误
问题根因
- 核心问题是栈缓冲区溢出破坏了套接字文件描述符
fd的有效性:你代码中char ui_request_str[] = ""仅分配了长度为1的栈内存(仅能存储空字符串的结束符\0),后续调用strcpy拷贝长度远大于1的JSON字符串时,会发生栈越界写入,直接覆盖栈上相邻的fd变量取值,导致fd从合法的套接字编号变为无效值,sendto调用时就会返回Bad File descriptor错误。 - 跨平台表现差异是因为Windows和Linux的栈内存布局、栈保护机制实现不同:当前代码在Windows环境下溢出的写入刚好未覆盖到
fd的存储位置,属于偶发的正常运行,不代表代码本身没有逻辑问题。
修复方案
- 分配足够大的静态缓冲区,根据业务预估JSON最大长度定义即可:
// 示例分配1024字节空间,可根据实际场景调整大小 char ui_request_str[1024] = {0}; strcpy(ui_request_str, json_object_to_json_string(hb));
- 更安全的动态内存分配方案:
const char* json_str = json_object_to_json_string(hb); size_t str_len = strlen(json_str); char* ui_request_str = malloc(str_len + 1); if (ui_request_str != NULL) { strcpy(ui_request_str, json_str); // 执行sendto逻辑 free(ui_request_str); }
- 无需额外拷贝的最优方案:直接使用
json_object_to_json_string返回的字符串指针调用sendto,省去拷贝步骤:
const char* json_str = json_object_to_json_string(hb); ssize_t send_len = sendto(fd, json_str, strlen(json_str), 0, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
内容的提问来源于stack exchange,提问作者Report Feedback
相关产品推荐
相关产品推荐

