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

Socket服务端返回多余字符及重复PuTTy标识问题求助

Socket服务端返回多余字符问题的修复方案

问题根源

  1. 未正确终止接收的字符串:网络传输的数据不会自动以\0结尾,直接用strlen(buffer)会读取缓冲区中残留的旧数据,导致处理范围错误。
  2. 发送了整个缓冲区的冗余数据:send(clientfd, buffer, sizeof(buffer), 0)会把256字节的缓冲区全部发送,包括有效字符后的垃圾数据。
  3. Telnet协议的额外报文干扰:PuTTy作为Telnet客户端,会发送终端协商的控制报文,这些数据被当作普通字符串处理后,就会出现奇怪的重复标识或字符。

修复后的代码

#include <io.h>
#include <stdio.h>
#include <winsock2.h>
#include <string.h>

#define MY_PORT     8989
#define MAXBUF      256

int main(int argc, char *argv[]){
    WSADATA wsa;
    SOCKET sockfd ,clientfd;
    struct sockaddr_in self;
    char buffer[MAXBUF];

    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0){
        printf("Failed. Error Code : %d",WSAGetLastError());
        return 1;
    }
    printf("Initialised.\n");

    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ){
        perror("Socket");
        exit(errno);
    }
    printf("Socket created.\n");

    self.sin_family = AF_INET;
    self.sin_port = htons(MY_PORT);
    self.sin_addr.s_addr = INADDR_ANY;

    if ((bind(sockfd, (struct sockaddr*)&self, sizeof(self)))!=0){
        perror("socket--bind");
        exit(errno);
    }
    puts("Bind done");

    if ((listen(sockfd, 20))!=0){
        perror("socket--listen");
        exit(errno);
    }
    puts("Waiting for incoming connections...");

    while (1){
        struct sockaddr_in client_addr;
        int addrlen=sizeof(client_addr);

        clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &addrlen);

        // 接收数据,预留1字节空间放终止符
        int length=recv(clientfd, buffer, MAXBUF-1, 0);
        if(length <=0){
            close(clientfd);
            continue;
        }
        buffer[length] = '\0'; // 手动添加字符串终止符,核心修复点1

        // 转小写
        for(int i=0; buffer[i]!='\0'; i++){
            if(buffer[i]>=65 && buffer[i]<=90){
                buffer[i]= buffer[i]+32;
            }
        }

        // 反转字符串
        int loop=0, len=strlen(buffer);
        char temp;

        len--;
        while (loop<len){
            temp=buffer[loop];
            buffer[loop]=buffer[len];
            buffer[len]=temp;
            loop++;
            len--;
        }

        // 只发送有效字符串长度,核心修复点2
        send(clientfd, buffer, strlen(buffer), 0);

        close(clientfd);
    }

    close(sockfd);
    WSACleanup();
    return 0;
}

关键修改说明

  • 接收数据时预留1字节空间,手动添加\0终止符,确保strlen能正确计算有效字符串长度,避免读取缓冲区残留的脏数据。
  • 发送时使用strlen(buffer)代替sizeof(buffer),只发送处理后的有效字符,避免冗余数据被发送。
  • 增加recv返回值判断,接收失败时直接关闭连接,避免无效处理。

关于Telnet标识重复的补充处理

如果仍有PuTTy标识重复的问题,是因为Telnet客户端会在连接建立时发送终端协商的控制报文。你可以在添加终止符后增加过滤逻辑(仅保留可打印字符和换行/回车):

// 过滤Telnet控制字符(可选)
int valid_idx = 0;
for(int i=0; buffer[i]!='\0'; i++){
    if(buffer[i] >= 32 || buffer[i] == '\r' || buffer[i] == '\n'){
        buffer[valid_idx++] = buffer[i];
    }
}
buffer[valid_idx] = '\0';

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 05:10:42