номер порта сокета UDP

#c #sockets #udp #port #sockaddr-in

#c #сокеты #udp #порт #sockaddr-вход

Вопрос:

Моя ОС — Ubuntu 20.x . У меня есть две программы: server.c которая прослушивает INADDR_ANY порт 2052 и client.c которая отправляет UDP-пакеты локально INADDR_LOOPBACK на тот же порт.

Программы работают нормально, и полученные данные и IP-адрес совпадают с отправленными; однако номера портов не совпадают. Я вижу, netstat что server.c это прослушивает правильный порт ( 2052 ), и я преобразую номер порта в локальный конечный код, поэтому я понятия не имею, что я делаю не так.

server.c :

 #define MY_PORT 2052

int main (void)
{
    int socket_descriptor = socket(AF_INET, SOCK_DGRAM, 0);
    struct sockaddr_in server_socket = {.sin_addr = {.s_addr = htonl(INADDR_ANY)}, .sin_port = htons(MY_PORT), .sin_family = AF_INET, .sin_zero = {0}};

    bind(socket_descriptor, (struct sockaddr *) amp;server_socket, sizeof(server_socket));


    char client_msg[SIZE   1] = {0};
    struct sockaddr_in client_socket;
    socklen_t addrlen = sizeof(client_socket);


    ssize_t received_bytes = recvfrom(socket_descriptor, client_msg, SIZE, 0, (struct sockaddr*) amp;client_socket, amp;addrlen);

    // this prints the data sent as expected : 
    printf("received %ld bytes of data : data was %sn", received_bytes, client_msg);
    // this prints 127.0.0.1 as expected :
    printf("the client IP address was %sn", inet_ntop(AF_INET, amp;client_socket.sin_addr, (char [INET_ADDRSTRLEN]) {0},  INET_ADDRSTRLEN));
    // this prints the WRONG port :
    printf("the port was %dn", ntohs(client_socket.sin_port));
    
    close(socket_descriptor);
}
  

client.c :

 #define MY_PORT 2052

int main (void)
{
    int socket_descriptor = socket(AF_INET, SOCK_DGRAM, 0);

    struct sockaddr_in client_socket = {.sin_port = htons(MY_PORT), .sin_family = AF_INET, .sin_addr = {.s_addr = htonl(INADDR_LOOPBACK)}, .sin_zero = {0}};

    char buffer[SIZE] = "this is a test message";

    sendto(socket_descriptor, buffer, SIZE, 0, (struct sockaddr*)amp;client_socket, sizeof(client_socket));

    close(socket_descriptor);
}
  

Моя цель — получить правильный номер порта на стороне прослушивания (сервера). Спасибо за вашу помощь!

Комментарии:

1. опубликованный код не компилируется! Первый. поскольку в обеих программах отсутствуют необходимые #include инструкции для необходимых файлов заголовков. Вы ожидаете, что мы угадаем, какие заголовочные файлы (если таковые имеются) на самом деле использовались вашими программами?

2.OT: относительно: char buffer[SIZE] = "this is a test message"; sendto(socket_descriptor, buffer, SIZE, 0, (struct sockaddr*)amp;client_socket, sizeof(client_socket)); SIZE не определено и зачем его определять. Вместо этого позвольте компилятору определить размер. Предложить: char buffer[] = "this is a test message"; sendto(socket_descriptor, buffer, sizeof( buffer ), 0, (struct sockaddr*)amp;client_socket, sizeof(client_socket));

3. OT: относительно: ssize_t received_bytes = recvfrom(socket_descriptor, client_msg, SIZE, 0, (struct sockaddr*) amp;client_socket, amp;addrlen); В коде должна быть ошибка проверки возвращаемого значения received_bytes , если == 0, то другой конец соединения закрыт. если < 0, то некоторая ошибка связи и следует использовать perror() для вывода вашего сообщения об ошибке и текстовой причины, по которой система считает, что произошла ошибка.

4. @user3629249 Сообщение ниже уже ответило на мой вопрос. Мой фактический код был, конечно, намного длиннее, чем эти образцы, из-за проверки возвращаемого значения и тонны #include . Я предполагал, что ошибка должна быть достаточно тривиальной, чтобы опытный программист мог увидеть ее даже без компиляции программы, что оказалось правдой. Тем не менее, спасибо за ваш вклад.

Ответ №1:

Номер порта, который печатает сервер, является номером порта клиента. Это отличается от номера порта сервера. Затем сервер может использовать этот номер порта для отправки ответа обратно клиенту.

Кроме того, при отправке дейтаграммы UDP, если вы не привязаны к определенному порту, система выберет один наугад.

Комментарии:

1. … и клиент не смог привязаться к тому же порту, к которому сервер уже привязан в любом случае.

2. Спасибо, я совершенно неправильно понял, как работают порты: c