Libuv: Inconsistency between uv_udp_getsockname and netstat output.

Created on 11 Apr 2019  路  6Comments  路  Source: libuv/libuv

  • Version: 1.27
  • Platform: Linux 4.8.0-58-generic #63~16.04.1-Ubuntu SMP Mon Jun 26 18:08:51 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

I implemented simple program that listen on UDP port, after calling uv_udp_bind and uv_udp_recv_start I try to get listening port number via uv_udp_getsockname. The last function call is successful but the port address differ with the port address that I used in uv_udp_bind and the port address that returned by netstat -nupl command.

Also I should note that the netstat -nupl is correct and show my program listening on port 14525.

Here is the source code:

  int main() {
    uv_loop_t *loop = uv_default_loop();
    uv_udp_t recv_socket;
    struct sockaddr_in recv_addr;
    int len = 0;
    int ret = 0;

    uv_udp_init(loop, &recv_socket);
    uv_ip4_addr("0.0.0.0", 14525, &recv_addr);
    uv_udp_bind(&recv_socket, (const struct sockaddr *)&recv_addr,
                UV_UDP_REUSEADDR);
    uv_udp_recv_start(&recv_socket, alloc_buffer, on_read);
    ret = uv_udp_getsockname(&recv_socket, (struct sockaddr *)&recv_addr, &len);
    if (ret != 0) {
      printf("couldn't get sock name\n");
    }
    printf("listening on port %d for inbound RTP\n", recv_addr.sin_port);  // print 48440!!

    return uv_run(loop, UV_RUN_DEFAULT);

  }

All 6 comments

You shoud use ntohs to print the port:

printf("listening on port %d for inbound RTP\n", ntohs(recv_addr.sin_port)); 

Thanks @santigimeno. The issue resolved by using ntohs(recv_addr.sin_port), but now I want to use some random port for listening, so I used uv_udp_recv_start without calling uv_udp_bind before. The port that uv_udp_getsockname return in this case is 0. How can I get the port that uv_udp_recv_start choose to listen?

Yeah, not calling uv_udp_bind() should work. This code sample works for me:

#include "uv.h"

int main() {
    uv_loop_t *loop = uv_default_loop();
    uv_udp_t recv_socket;
    struct sockaddr_in recv_addr;
    int len = 0;
    int ret = 0;

    uv_udp_init(loop, &recv_socket);
    ret = uv_udp_getsockname(&recv_socket, (struct sockaddr *)&recv_addr, &len);
    if (ret != 0) {
      printf("couldn't get sock name\n");
    }
    printf("listening on port %d for inbound RTP\n", ntohs(recv_addr.sin_port));

    return uv_run(loop, UV_RUN_DEFAULT);
}

Wait, that's not correct.

Okay, updated the code. Just don't initialize the recv_addr and initialize len correctly and it should work:

int main() {
    uv_loop_t *loop = uv_default_loop();
    uv_udp_t recv_socket;
    struct sockaddr_in recv_addr;
    int len = sizeof(recv_addr);
    int ret = 0;

    uv_udp_init(loop, &recv_socket);
    uv_udp_recv_start(&recv_socket, alloc_cb, on_read);
    ret = uv_udp_getsockname(&recv_socket, (struct sockaddr *)&recv_addr, &len);
    if (ret != 0) {
      printf("couldn't get sock name\n");
    }
    printf("listening on port %d for inbound RTP\n", ntohs(recv_addr.sin_port));

    return uv_run(loop, UV_RUN_DEFAULT);
}

@santigimeno thanks a lot, it works now. The solution was so tricky, thanks again.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Archcry picture Archcry  路  6Comments

imran-iq picture imran-iq  路  7Comments

cjihrig picture cjihrig  路  12Comments

leonerd picture leonerd  路  11Comments

cjihrig picture cjihrig  路  5Comments