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

Linux C Socket服务端与Telnet客户端数据传输异常问题求助

问题原因及解决方法

问题根因梳理

1. 无法进入if (bytes_index > 0)代码块的核心原因

  • accept的第三个参数client_len未初始化:accept要求调用前必须将该参数设置为传入的地址结构体长度,否则会导致accept执行异常,后续收数据逻辑完全出错。
  • 换行处理逻辑有漏洞:仅在检测到行尾是\r时才给input赋值\0,如果收到的换行符不带\r,input就不是合法的C字符串,后续字符串操作会越界;且当输入的行没有\r时,处理完换行后bytes_index的值等于有效内容长度,若内容长度为1,bytes_index会变为0,无法满足>0的判断条件。
  • 打印语句参数类型错误触发段错误:用%s格式化输出input[0]这类单个字符,%s要求传入char*类型的字符串首地址,传入字符值会被当成非法内存地址,直接导致程序崩溃,自然看不到代码块内的输出。

2. bytes_index取值不符合预期的原因

  • 未处理recv返回0的异常分支:当客户端断开连接时recv返回0,此时会直接break退出收数据循环,bytes_index会停在异常递增后的值,不符合业务预期。
  • 换行处理的计数逻辑有漏洞:处理\n时直接bytes_index--,但没有考虑无\r的场景下的计数修正,导致有效长度统计错误。
  • 原accept报错打印缺少参数:代码中fprintf(stderr, "accept failed with error %d\n");没有传入错误值参数,会输出垃圾值干扰问题排查。

修复方案

1. 初始化必要参数,修正accept错误打印

在accept调用前添加client_len初始化,同时补全报错打印参数:

client_len = sizeof(struct sockaddr_in);
cfd = accept(rfd, (struct sockaddr *) &client, &client_len);
if (cfd < 0) {
    fprintf(stderr, "accept failed with error %d\n", cfd);
    exit(-1);
}

2. 修正换行处理逻辑,统一补字符串结束符

将收数据循环内的换行处理逻辑修改为:

if (input[bytes_index] == '\n') {
    // 先把\n替换成结束符
    input[bytes_index] = '\0';
    // 再处理\r的情况
    bytes_index--;
    if (bytes_index >=0 && input[bytes_index] == '\r') {
        input[bytes_index] = '\0';
    }
    break;
}

3. 修正判断条件和打印语句

  • 将if (bytes_index > 0)改为if (bytes_index >= 0 && strlen(input) > 0),避免短内容被过滤。
  • 打印单个字符的语句将%s改为%c:
printf("%c\n", input[0]); //G
printf("%c\n", input[1]); //e
printf("%c\n", input[2]); //t

4. 添加缓冲区溢出防护

在收数据循环内增加判断,避免bytes_index超过BUFSIZE-1,防止数组越界:

while (1) {
    // 新增缓冲区满判断
    if (bytes_index >= BUFSIZE -1) {
        input[BUFSIZE-1] = '\0';
        break;
    }
    bytes_read = recv(cfd, &input[++bytes_index], 1, 0);
    // 原有逻辑不变
    if (bytes_read <= 0)
        break;
    // 原有换行处理逻辑不变
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 01:06:04