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

C socket编程问题:实现telnet对接发送命令后仅打印一行问题排查

C语言Socket对接Telnet仅打印单行问题解决方案

核心原因定位

该异常90%以上场景由以下三类问题导致:

  • Telnet协议控制字节未过滤:Telnet传输内容中会穿插IAC(值为0xFF)开头的控制信令,若程序未识别该类字节,会将其误判为文本结束标记、或是异常截断后续内容
  • 接收逻辑存在缺陷:仅单次调用recv()就结束读取流程,未处理TCP流的粘包拆包特性,也未循环拉取内核缓冲区的剩余数据
  • 行结束符识别逻辑错误:Telnet标准行结束符为CRLF(\r\n),若程序仅以\n作为行分割标记,部分返回内容会被识别为单行长文本,或是出现回车符覆盖已有打印内容的异常,视觉上呈现为仅打印一行

修复方案

1. 新增Telnet控制字节过滤逻辑

读取字节时若检测到IAC控制标记,直接跳过对应控制序列,不纳入文本处理:

// Telnet文本读取函数,自动过滤控制信令
int telnet_read(int sockfd, char* out_buf, int buf_max_len) {
    int write_pos = 0;
    char tmp_byte;
    while (write_pos < buf_max_len - 1) {
        int ret = recv(sockfd, &tmp_byte, 1, 0);
        if (ret <= 0) return ret;
        
        // 处理Telnet IAC控制序列
        if (tmp_byte == 0xFF) {
            // 读取命令字节
            recv(sockfd, &tmp_byte, 1, 0);
            // 带参数的控制命令需要多跳过一个字节
            if (tmp_byte >= 0xFB && tmp_byte <= 0xFE) {
                recv(sockfd, &tmp_byte, 1, 0);
            }
            continue;
        }
        out_buf[write_pos++] = tmp_byte;
        // 可选:按行读取时读到换行符即可返回,不需要按行读取可删除该判断
        if (tmp_byte == '\n') break;
    }
    out_buf[write_pos] = '\0';
    return write_pos;
}

2. 修正接收循环逻辑

持续调用读取函数直到连接断开,不要单次读取就终止流程:

char recv_buffer[1024];
int read_len;
while ((read_len = telnet_read(sock_fd, recv_buffer, sizeof(recv_buffer))) > 0) {
    printf("%s", recv_buffer);
    memset(recv_buffer, 0, sizeof(recv_buffer));
}

3. 统一行结束符处理

将读取到的\r\n序列统一替换为\n,避免回车符导致的打印内容被覆盖问题。

校验方法

  • 打印所有接收字节的十六进制值,确认是否存在未过滤的Telnet控制字节,以及行结束符格式是否符合预期
  • 打印每次recv()调用的返回值,确认是否存在单次读取未拉取全量数据的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 23:09:03