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!
问题原因与修复方案
核心问题
- 缺少字符串终止符:
recv接收的是原始字节流,不会自动添加\0终止符。缓冲区未被填满时,剩余空间是栈上的随机垃圾数据。 - 打印长度错误:
printf("%.*s", sizeof(buffer)-1, buffer)中,第二个参数误用了缓冲区最大长度,而非recv实际接收的字节数recvd。客户端看似正常只是巧合——其栈中缓冲区剩余位置恰好存在\0,截断了垃圾数据。
修复步骤
在客户端和服务器的recv操作成功后,添加以下两步:
- 手动为缓冲区添加字符串终止符,避免越界访问:
buffer[recvd] = '\0';
- 修改
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
相关产品推荐
相关产品推荐

