c语言 - 消息不会打印在服务器端 - 套接字



我在Linux上尝试这个,我是C语言套接字的新手,我确实用C创建了一个客户端和一个服务器,当我发送一条消息时,它工作得很好,但当我循环它以继续聊天时,除了第一条消息外,消息不会在服务器端打印出来,我正在本地主机上尝试这个这是客户端代码:

#include<stdio.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
int main(){
char msg[30] = {0};
struct sockaddr_in server;
struct sockaddr_in *ptr= &server;
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if(socket_fd < 0){
perror("socket");
return 1;
}
ptr -> sin_family = AF_INET;
ptr -> sin_port = htons(10000);
ptr -> sin_addr.s_addr = INADDR_ANY;
int con = connect(socket_fd,(struct sockaddr *) &server, sizeof(server));
if(con < 0){
perror("connect");
return 1;
}
do{
memset(msg, 0, sizeof(msg));
fputs("client : ",stdout);
fgets(msg, sizeof(msg), stdin);
if(send(socket_fd, msg, sizeof(msg), 0) < 0){
perror("send");
return 1;
}
if(strncmp(msg, "!quit", 5) == 0)
break;
memset(msg, 0, sizeof(msg));
if(recv(socket_fd ,msg, sizeof(msg), 0) < 0){
perror("recv");
return 1;
}
printf("server : %sn",msg);
}while(strncmp(msg,"!quit", 5) != 0);
puts("connection closed!");
close(socket_fd);
return 0;

}

这是服务器代码:

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
int main(){
char msg[100] = {0};
struct sockaddr_in server;
struct sockaddr_in *ptr = &server;
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
if(server_socket < 0){
perror("socket");
return 1;
}
ptr-> sin_family = AF_INET;
ptr-> sin_port = htons(10000);
ptr-> sin_addr.s_addr = INADDR_ANY;
if(bind(server_socket, (struct sockaddr *)&server, sizeof(server)) < 0){
perror("bind");
return 1;
}
if(listen(server_socket, 1) < 0){
perror("listen");
return 1;
}
int client_socket;
if((client_socket = (accept(server_socket, NULL, NULL))) < 0){
perror("accept");
return 1;
}
do{
memset(msg, 0, sizeof(msg));
if(recv(client_socket, msg, sizeof(msg), 0) < 0){
perror("recv");
return 1;
}
printf("client : %sn",msg);
if(strncmp(msg, "!quit", 5) == 0)
break;
memset(msg, 0, sizeof(msg));
fputs("server : ",stdout);
fgets(msg, sizeof(msg), stdin);
if(send(client_socket, msg, sizeof(msg), 0) < 0){
perror("send");
return 1;
}
}while(strncmp(msg, "!quit", 5) != 0);
puts("connection closed!");
close(client_socket);
close(server_socket);
return 0;

}

如果你有任何关于插座、最佳实践、速度的提示。。。。我会很高兴听到的。

在服务器中,您使用msg作为100字节的缓冲区。所以当你打电话给

send(client_socket, msg, sizeof(msg), 0)

您正在发送100个字节,但在客户端,您正在为大小为30个字节的缓冲区调用recv,因此您需要调用recv4次才能读取100个字节:30 + 30 + 30 + 10。您可以将服务器端的msg缓冲区填充为a:

memset(msg, 'a', sizeof(msg));
fputs("server : ",stdout);
fgets(msg, sizeof(msg), stdin);
if(send(client_socket, msg, sizeof(msg), 0) < 0){

现在,如果你启动这两个程序,你会看到这样的东西:

Client             | Server
-----------------------------------------
send `request1`    |  
| got `request1`
| send 'response1'
got 'response1'    |
send 'request2'    |
| got 'reguest2'
| send 'response2'
!!!!               | 
got `aaaaaaaaa...` |
got `aaaaa'        |
after first 100 B  |
were read you can  |
see response2 here | 

通过将所有字节填充到a,您可以看到数据正在接收,直到客户端读取了100个字节。当缓冲区由NULL字节填充时,您将看不到消息,因为printf的NULL字节表示字符串的末尾(消息已被读取,但若printf函数使用的第一个字节为NULL字节,您将无法看到它(。

使用strlen并将send的调用更改为:

send(client_socket, msg, strlen(msg), 0)
^^^^^^^^^^^ returns the length of entered message

最新更新