Сообщения не печатаются на стороне сервера - сокеты - PullRequest
0 голосов
/ 07 декабря 2018

Я пытаюсь это сделать в 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 : %s\n",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 : %s\n",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;

}

также, если у вас есть какие-либо советы по поводу сокетов, наилучшей практики, скорости .... я буду рад это услышать.

1 Ответ

0 голосов
/ 07 декабря 2018

На сервере вы используете msg в качестве буфера 100 байт.Поэтому, когда вы вызываете

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

, вы отправляете 100 байтов, но на стороне клиента вы вызываете recv для буфера, размер которого составляет 30 байтов, поэтому вам нужно вызвать recv 4 разачитать 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-байтами, вы не можете видеть сообщение, потому что NULL-байты для printf означают конец строки (сообщение было прочитано, но вы не можете увидеть его, если первый байт, который принимает функция printf, равен NULL-байту).

Используйте strlen и измените вызов send на:

send(client_socket, msg, strlen(msg), 0)
                         ^^^^^^^^^^^ returns the length of entered message
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...