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

C语言Socket客户端突然断开时服务器Segfault段错误如何解决

问题解决与代码优化方案

一、段错误核心原因与修复

段错误的根本原因是服务端检测到客户端断开后,没有终止当前连接的处理逻辑,后续对空数据做字符串拆分、数组访问触发了空指针解引用:
当客户端突然断开时,服务端read调用返回0,你仅将clientSocket[h]设为0,没有跳过后续的报文处理代码,此时msg缓冲区无有效数据,strtok返回NULL,arr[0]、arr[1]都是野指针,访问直接触发段错误。

修复代码片段(服务端read逻辑部分)

READ = read(sd, msg, sizeof(msg));
if (READ == -1) {
    perror("Could not receive message");
    close(sd);
    clientSocket[h] = 0;
    continue; // 出错只关闭当前连接,不要退出整个服务端
}
if (READ == 0) {
    printf("Client disconnected\n");
    fflush(stdout);
    close(sd); // 必须关闭断开的socket,避免资源泄漏
    clientSocket[h] = 0;
    continue; // 跳过后续报文处理逻辑,避免访问无效数据
}
// 手动给read到的数据加字符串结束符,read不会自动补
msg[READ] = '\0';

int e = 0;
char *p = strtok(msg, " ");
char *arr[2];
// 加边界判断,避免数组越界
while (p != NULL && e < 2) {
    arr[e++] = p;
    p = strtok(NULL, " ");
}
// 必须校验参数数量,避免非法报文触发越界
if (e != 2) {
    strcpy(reply, "Input error: please send two numbers separated by space\n");
    write(sd, reply, strlen(reply));
    continue;
}

修改后即可解决客户端断开触发的段错误问题。

二、其他可优化点

  • 资源泄漏修复:原来的代码不管是连接出错还是客户端断开,都没有调用close(sd)释放文件描述符,长期运行会耗尽系统socket资源
  • 服务端可用性优化:原来代码只要单连接出错就直接退出整个服务端,改成仅关闭出错的客户端连接,服务端持续运行
  • 输入安全修复:客户端scanf("%s", buf)没有限制输入长度,容易触发栈溢出,改成scanf("%1023s", buf)限制输入长度;fflush(stdin)是C标准未定义行为,不要使用,可用getchar()循环读走缓冲区残留数据
  • TCP粘包处理:当前代码没有处理TCP粘包问题,可能出现一次read读到多组报文、或者一组报文被拆分多次读取的情况,建议约定消息边界(比如固定长度、或者用换行符作为结束标识)
  • 规范变量命名:不要用READ、SELECT、ACCEPT这类和系统调用同名的变量,容易引发编译或逻辑异常,改成read_len、select_ret、accept_fd这类自定义命名
  • 输入校验优化:atoi无法区分输入是0还是非法字符串,建议换成strtol做数字转换,可以明确检测转换失败的场景
  • 逻辑bug修复:accept的第二个参数是用来存储客户端地址的,你当前传了&server会覆盖服务端地址配置,改成&client即可;listen的backlog参数设为1太小,并发稍高就会拒绝连接,可改成10或更大值

内容的提问来源于stack exchange,提问作者user14773854

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 21:24:05