Use bind to bind your socket to port 0, which allows you to use getsockname to get the port. You can also bind your socket to a specific port if you want.
for example (assuming the IPv4 socket, error checking):
struct sockaddr_in sin = {}; socklen_t slen; int sock; short unsigned int port; sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = 0; bind(sock, (struct sockaddr *)&sin, sizeof(sin)); slen = sizeof(sin); getsockname(sock, (struct sockaddr *)&sin, &slen); port = ntohs(sin.sin_port);
Alternatively, if you are communicating with the same server, you can use connect in your UDP socket (which also gives you a convenient side effect that allows you to use send instead of sendto and the UDP socket only accepts datagrams from your βconnectedβ peer), then use getsockname to get the local port / address. You can still bind your socket before using connect .
eg:
struct sockaddr_in sin = {}; socklen_t slen; int sock; short unsigned int port; sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); ... connect(sock, (struct sockaddr *)&sin, sizeof(sin)); slen = sizeof(sin); getsockname(sock, (struct sockaddr *)&sin, &slen); port = ntohs(sin.sin_port);
source share