C语言Socket问题:客户端输入后服务器返回内容含多余字符
客户端-服务器Socket程序返回消息末尾带多余字符问题解决
我正在实现一个客户端-服务器Socket程序,程序接受键盘输入并将输入字符串作为请求发送至服务器,但目前遇到的问题是:客户端向服务器发送内容时,返回的消息末尾总是带有多余字符。
服务器代码
#include <unistd.h> #include <stdio.h> #include <sys/socket.h> #include <stdlib.h> #include <netinet/in.h> #include <string.h> #include <arpa/inet.h> int main(int argc, char *argv[]){ int socket_desc, c; ssize_t read_size; int client_socket ; struct sockaddr_in server, client; // 创建socket socket_desc = socket(AF_INET, SOCK_STREAM,0); if (socket_desc==-1){ printf("Could not create socket."); } puts("Socket created"); // 填充服务器地址结构 server.sin_addr.s_addr = inet_addr("127.0.0.1"); server.sin_family = AF_INET; server.sin_port = htons(8888); // 绑定socket到端口 if(bind(socket_desc,(struct sockaddr *)&server, sizeof(server))<0){ perror("bind failed. error"); return 1; } puts("bind done"); // 监听连接 listen(socket_desc,3); puts("waiting for incoming connections..."); c = sizeof(struct sockaddr_in); client_socket= accept(socket_desc,(struct sockaddr *)&client, (socklen_t*)&c); if (client_socket == -1) { perror("accept failed"); return 1; } puts("Connection accepted"); while(1){ char client_message[1000]; recv(client_socket, client_message, 2000,0); puts(client_message); write(client_socket,client_message, strlen(client_message)); } if(read_size==0){ puts("client disconnected"); fflush(stdout); } else if(read_size==-1){ perror("recv failed"); } return 0; }
客户端代码
#include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> #include <string.h> #include <unistd.h> int main(int argc, char *argv[]) { int sock; struct sockaddr_in server; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1) printf("ERROR opening socket"); puts("Socket created"); server.sin_addr.s_addr=inet_addr("127.0.0.1"); server.sin_family = AF_INET; server.sin_port = htons(8888); if (connect(sock,(struct sockaddr *)&server,sizeof(server)) < 0){ printf("ERROR connecting"); return 1; } puts("Connected"); while(1){ char message[1000], server_reply[2000]; printf("Please enter the message: "); scanf("%s",message); puts(message); if (send(sock,message,strlen(message),0)< 0){ printf("ERROR writing to socket"); return 1; } if (recv(sock,server_reply,2000,0)<0){ puts("recv failed"); break; } puts("server reply"); puts(server_reply); } close(sock); return 0; }
问题原因
核心问题是C语言字符串缺少终止符\0:
- 服务器端
recv仅将字节数据写入缓冲区,但不会自动添加\0。strlen、puts等函数依赖\0判断字符串结束位置,否则会读取缓冲区后续的垃圾内存数据。 - 客户端的
server_reply缓冲区未每次清空,前一次接收的残留数据会被后续输出带出。
修正方案
服务器代码修改
// 替换原while循环部分 while(1){ char client_message[1000]; // 保存recv的实际接收长度 ssize_t recv_len = recv(client_socket, client_message, sizeof(client_message)-1, 0); if (recv_len <= 0) { if (recv_len == 0) { puts("client disconnected"); } else { perror("recv failed"); } break; } // 手动添加字符串终止符 client_message[recv_len] = '\0'; puts(client_message); write(client_socket, client_message, strlen(client_message)); }
同时修正main函数参数的拼写错误:将int argv, char *afgv[]改为int argc, char *argv[]。
客户端代码修改
// 替换原while循环部分 while(1){ char message[1000], server_reply[2000]; // 每次接收前清空缓冲区,避免残留数据 memset(server_reply, 0, sizeof(server_reply)); printf("Please enter the message: "); scanf("%s",message); puts(message); if (send(sock,message,strlen(message),0) < 0){ printf("ERROR writing to socket"); return 1; } ssize_t recv_len = recv(sock, server_reply, sizeof(server_reply)-1, 0); if (recv_len < 0){ puts("recv failed"); break; } // 添加终止符 server_reply[recv_len] = '\0'; puts("server reply"); puts(server_reply); }
额外注意事项
recv的第三个参数要设置为缓冲区大小-1,预留位置给\0,避免缓冲区溢出。- 必须检查
recv的返回值,及时处理客户端断开或接收失败的情况,防止死循环。 - 如果需要支持带空格的输入,可将
scanf("%s", message)替换为fgets(message, sizeof(message), stdin),注意处理换行符。
内容的提问来源于stack exchange,提问作者Jake
相关产品推荐
相关产品推荐

