C语言Socket服务端仅能发送单条消息问题排查求助
C语言Socket通信问题:服务端无法响应客户端WORD消息
我用C语言写的Socket服务端,现在只能给客户端发送HELLO消息,客户端发送WORD消息后,服务端本该返回GREEK,但一直发不出去。已经确认connect、bind、socket、listen、accept这些调用都没问题,试过write、send等多种发送方式还是不行。
服务端核心代码
while (1) { if ((newsockfd = accept(sockfd, (struct sockaddr *)&dest, &destlen)) == -1) { perror("Accept call failed"); exit(-1); } if ((childpid = fork()) == 0) { //close(sockfd); talk_to_client(newsockfd); //close(newsockfd); } else if (childpid > 0) { //close(newsockfd); } } }
talk_to_client()函数代码
void talk_to_client(int sockfd) { char message[1024] = "HELLO"; char message2[1024] = "GREEK"; char recieved[1024]; ssize_t n; //cannot send more than one!!!!!!!!! WHY NOT write(sockfd, message, sizeof(message)); while (1) { recv(sockfd, recieved, sizeof(recieved), 0); if (recieved == "WORD") { //send initial word printf("SENDING WORD"); write(sockfd, message2, sizeof(message2)); } if (recieved == "QUIT") { //close connection close(sockfd); } } return; }
客户端核心代码
char srv[512]; char cli[512] = "WORD"; // Connects socket to server rv = connect(sockfd, (struct sockaddr *) servaddr, sizeof(struct sockaddr)); if (rv == -1){ perror("Error connecting to the server"); exit(-1); } if(recv(sockfd, srv, sizeof(srv), 0) == -1) { perror("Client receiving error"); } printf("Client received: %s\n", srv); if(send(sockfd, cli, sizeof(cli), 0) == -1){ perror("Error sending message to the server"); exit(-1); } printf("Client sending: %s\n", cli); if(recv(sockfd, srv, sizeof(srv), 0) == -1) { perror("Client receiving error"); } printf("Client received: %s\n", srv); close(sockfd);
当前输出
Client received: HELLO Client sending: WORD Client received:
问题根源
- 字符串比较错误:C语言中不能用
==直接比较字符串内容,这是在比较两个字符串的指针地址,肯定不相等。必须用strcmp()函数来比较字符串内容。 - 发送数据长度错误:不管是服务端发HELLO,还是客户端发WORD,都用了
sizeof()来指定发送长度,这会把整个数组的1024/512字节都发出去,包括后面的空字符,导致服务端接收到的内容不是纯"WORD",strcmp自然匹配不上。应该发送字符串的实际长度,用strlen() + 1(加1是为了包含终止符\0)。 - recv返回值未处理:recv的返回值表示实际接收到的字节数,不处理的话不知道有没有接收到数据,甚至可能接收失败还在继续处理。而且recv后需要手动给缓冲区加终止符,否则字符串函数会读取到垃圾数据。
- 服务端循环未处理客户端断开:当客户端断开连接后,recv会返回-1,此时应该退出循环并关闭socket。
修改后的关键代码片段
服务端talk_to_client函数修改:
void talk_to_client(int sockfd) { char message[1024] = "HELLO"; char message2[1024] = "GREEK"; char recieved[1024]; ssize_t n; // 只发送实际字符串长度(包含\0) write(sockfd, message, strlen(message) + 1); while (1) { // 接收数据并检查返回值,预留一个字节给终止符 n = recv(sockfd, recieved, sizeof(recieved) - 1, 0); if (n <= 0) { // 客户端断开或接收失败,退出循环 close(sockfd); break; } // 手动添加字符串终止符 recieved[n] = '\0'; if (strcmp(recieved, "WORD") == 0) { printf("SENDING WORD\n"); // 发送GREEK的实际长度 write(sockfd, message2, strlen(message2) + 1); } if (strcmp(recieved, "QUIT") == 0) { close(sockfd); break; } } return; }
客户端发送部分修改:
// 只发送WORD的实际长度(包含\0) if(send(sockfd, cli, strlen(cli) + 1, 0) == -1){ perror("Error sending message to the server"); exit(-1); }
另外,建议补上服务端fork后、客户端退出时的socket关闭操作,避免资源泄漏。
内容的提问来源于stack exchange,提问作者gabekl22
相关产品推荐
相关产品推荐

