Не получается вывод на стороне клиента (сокет UDP в C) - PullRequest
0 голосов
/ 09 апреля 2020

Вот мой код для серверной и клиентской стороны сокета UDP.

Проблема в том, что когда я запускаю это в терминале, выполнение сервера останавливается, как только клиент достигает сервера , но на стороне клиента я не получил никаких данных.

Клиент. c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    int network_socket;

    network_socket = socket(AF_INET, SOCK_DGRAM, 0);

    struct sockaddr_in server_address;

    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = INADDR_ANY;

    sendto(network_socket, 0, 0, MSG_CONFIRM, (const struct sockaddr *) &server_address, sizeof(server_address));
    char server_response[256];
    int len = sizeof(network_socket);
    int = recvfrom(network_socket, &server_response, sizeof(server_response), 0,(struct sockaddr*) &network_socket, (socklen_t*)&len);

    printf("The server sent the data : %s\n", server_response);

    close(network_socket);
    return 0;
}

Сервер. c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    char server_message[256] = "you have reached the UDP server";

    int server_socket,client_address;
    server_socket = socket(AF_INET, SOCK_DGRAM,0);

    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = INADDR_ANY;

    bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address));

    int n,len;
    len = sizeof(client_address);
    n = recvfrom(server_socket, server_message, sizeof(server_message), 0, (struct sockaddr *) &client_address, (socklen_t*)&len);

    sendto(server_socket, server_message, sizeof(server_message), 0, (struct sockaddr *) &client_address, len);
    close(server_socket);
    return 0;
}

Ответы [ 2 ]

1 голос
/ 09 апреля 2020
sendto(network_socket, 0, 0, MSG_CONFIRM, (const struct sockaddr *) &server_address, sizeof(server_address));

Вы не отправляете никаких данных.

int = recvfrom(network_socket, &server_response, sizeof(server_response), 0,(struct sockaddr*) &network_socket, (socklen_t*)&len);

printf("The server sent the data : %s\n", server_response);

Вы не сохранили количество полученных байтов, вот что возвращает recvfrom. Таким образом, вы не знаете, сколько данных вы получили. Затем вы пытаетесь распечатать эти данные через %s, то есть только для строк C. Вы не можете использовать его для печати произвольных данных. Как минимум, вы должны указать ему, сколько данных нужно напечатать (в противном случае, откуда он это может знать?), И вы выбросили эту информацию.

0 голосов
/ 09 апреля 2020

С обеих сторон вы вообще не обрабатываете ошибки.

На стороне клиента вы не можете отправлять дейтаграммы на INADDR_ANY, вам нужно отправить на фактический IP-адрес. И при вызове recvfrom() вы используете файловый дескриптор network_socket в качестве структуры sockaddr_in для получения адреса / порта отправителя, что просто неверно.

На стороне сервера вы объявляете client_address как int, когда вместо него должна быть структура sockaddr_in. И вы используете тот же самый буфер char[] для получения данных клиента, который вы используете для хранения приветствия вашего сервера, так что вы фактически отражаете то, что отправляет клиент (что ничего), но вы не берете размер Данные клиента в учет. И вы неправильно используете printf() после выхода recvfrom(), поскольку клиент не отправляет строку с нулевым символом в конце, но %s ожидает ее.

Попробуйте вместо этого:

Клиент. c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main()
{
    int network_socket = socket(AF_INET, SOCK_DGRAM, 0);
    if (network_socket < 0)
    {
        perror("socket() failed");
        return -1;
    }

    struct sockaddr_in server_address;

    bzero(&server_address, sizeof(server_address));
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = inet_addr("Server IP Address Here"); // or "127.0.0.1" for localhost

    if (sendto(network_socket, 0, 0, MSG_CONFIRM, (struct sockaddr *) &server_address, sizeof(server_address)))
    {
        perror("sendto() failed");
        close(network_socket);
        return -1;
    }

    char server_response[256];

    struct sockaddr_in sender_address;
    socklen_t addrlen = sizeof(sender_address);

    int n = recvfrom(network_socket, server_response, sizeof(server_response), 0, (struct sockaddr*) &sender_address, &addrlen);
    // or, since you are not using the sender's sockaddr_in for anything:
    // int n = recvfrom(network_socket, server_response, sizeof(server_response), 0, NULL, NULL);
    if (n < 0)
    {
        perror("recvfrom() failed");
        close(network_socket);
        return -1;
    }

    printf("The server sent the data : %.*s\n", n, server_response);

    close(network_socket);
    return 0;
}

Сервер. c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main()
{
    char server_message[] = "you have reached the UDP server";

    int server_socket = socket(AF_INET, SOCK_DGRAM, 0);
    if (server_socket < 0)
    {
        perror("socket() failed");
        return -1;
    }

    struct sockaddr_in server_address;

    bzero(&server_address, sizeof(server_address));
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = INADDR_ANY;

    if (bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address)) < 0)
    {
        perror("bind() failed");
        close(server_socket);
        return -1;
    }

    char client_message[256];

    struct sockaddr_in client_address;
    socklen_t addrlen = sizeof(client_address);

    int n = recvfrom(server_socket, client_message, sizeof(client_message), 0, (struct sockaddr *) &client_address, &addrlen);
    if (n < 0)
    {
        perror("recvfrom() failed");
        close(server_socket);
        return -1;
    }

    printf("The client sent the data : %.*s\n", n, client_message);

    if (sendto(server_socket, /*client_message*/server_message, /*n*/strlen(server_message), 0, (struct sockaddr *) &client_address, addrlen) < 0)
    {
        perror("sendto() failed");
        close(server_socket);
        return -1;
    }

    close(server_socket);
    return 0;
}
...