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

Linux Socket通信中服务器printf输出含垃圾数据问题求助

问题描述

在Debian虚拟机上实现了一个Linux客户端-服务器Socket程序,功能为:

  • 服务器向客户端发送字符串,客户端打印该字符串
  • 客户端向服务器发送字符串,服务器打印该字符串

当前异常:客户端打印字符串完全正常,但服务器打印时,输出内容后会在新行出现♦这类垃圾数据。已排查指针、写入操作,尝试过fflush(stdout)及调整指针,均无效;移除服务器printf中的".*"会触发段错误。

客户端代码
#include <stdio.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <unistd.h>

int main() {
    //create server info
    struct sockaddr_in server_info = {0};
    server_info.sin_family = AF_INET;
    server_info.sin_addr.s_addr = htonl(0x7f000001);
    server_info.sin_port = htons(25565);

    socklen_t server_info_len = sizeof(server_info);

    //create client socket
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket");
        return -1;
    }

    //connect to server
    if (connect(sockfd, (struct sockaddr*)&server_info, server_info_len) < 0) {
        perror("connect");
        return -1;
    }

    char buffer[1024];

    //recieve message
    ssize_t recvd = recv(sockfd, buffer, sizeof(buffer)-1, 0);

    if (recvd < 0) {
        perror("recv");
        return -1;
    }

    //print message
    printf("%.*s", sizeof(buffer)-1, buffer);

    //send client message
    char* sentFromClient = "Sent from client!\n";
    ssize_t sent = send(sockfd, (void*)sentFromClient, strlen(sentFromClient), 0);
    if (sent < 0) {
        perror("send");
        return -1;
    }

    //close socket
    if (close(sockfd) < 0) {
        perror("close");
        return -1;
    }

    return 0;
}
服务器代码
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>

int main() {
    //create server structures
    struct sockaddr_in server_info = {0};

    server_info.sin_family = AF_INET;
    server_info.sin_port = htons(25565);

    socklen_t server_info_len = sizeof(server_info);

    //create client structures for server use
    struct sockaddr client_info = {0};
    socklen_t client_info_len = sizeof(client_info);

    //create our socket
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket");
        return -1;
    }

    //bind socket
    if (bind(sockfd, (struct sockaddr*)&server_info, server_info_len) < 0) {
        perror("bind");
        return -1;
    }

    //listen on port
    if (listen(sockfd, 0) < 0) {
        perror("listen");
        return -1;
    }

    //accept client
    int clientfd = accept(sockfd, &client_info, &client_info_len);
    if (clientfd < 0) {
        perror("accept");
        return -1;
    }

    //send client message
    char* sentViaServer = "From Server!\n";
    ssize_t sent = send(clientfd, (void*)sentViaServer, strlen(sentViaServer), 0);

    if (sent < 0) {
        perror("send");
        return -1;
    }

    //recieve client message
    char buffer[1024];
    ssize_t recvd = recv(clientfd, buffer, sizeof(buffer)-1, 0);
    if (recvd < 0) {
        perror("recv");
        return -1;
    }

    //print client message
    printf("%.*s", sizeof(buffer)-1, buffer);

    //close socket
    if (close(clientfd) < 0) {
        perror("close");
        return -1;
    }

    if (close(sockfd) < 0) {
        perror("close");
        return -1;
    }
    return 0;
}
输出情况
  • 服务器输出:Sent from client!后跟随新行及♦类垃圾字符
  • 客户端输出:正常显示From Server!
问题原因与修复方案

核心问题

  1. 缺少字符串终止符:recv接收的是原始字节流,不会自动添加\0终止符。缓冲区未被填满时,剩余空间是栈上的随机垃圾数据。
  2. 打印长度错误:printf("%.*s", sizeof(buffer)-1, buffer)中,第二个参数误用了缓冲区最大长度,而非recv实际接收的字节数recvd。客户端看似正常只是巧合——其栈中缓冲区剩余位置恰好存在\0,截断了垃圾数据。

修复步骤

在客户端和服务器的recv操作成功后,添加以下两步:

  1. 手动为缓冲区添加字符串终止符,避免越界访问:
buffer[recvd] = '\0';
  1. 修改printf的长度参数为实际接收的字节数,或直接用%s格式符(因为已添加终止符):
// 二选一即可
printf("%.*s", (int)recvd, buffer);
// 或
printf("%s", buffer);

修复后的服务器接收打印示例

//recieve client message
char buffer[1024];
ssize_t recvd = recv(clientfd, buffer, sizeof(buffer)-1, 0);
if (recvd < 0) {
    perror("recv");
    return -1;
}
buffer[recvd] = '\0'; // 添加终止符
printf("%s", buffer); // 直接打印有效内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 21:50:22