2
votes

I'm writing a very small C UDP client. I know that a random port is chosen as source port when you send data to the server. I also know that you can use bind to specify yourself the port you want a response.

However, I don't know when is the port randomly chosen? For example, I would like to rely on the sender address to keep track of users. It currently works only if the client does not shutdown, the port is still the same then a simple memcmp is enough to detect the same client.

This small code will use the same source port until it exits:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>

int main(void)
{
    int s, error, ch;
    struct addrinfo hints, *res;

    memset(&hints, 0, sizeof (struct addrinfo));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;

    if ((error = getaddrinfo("localhost", "9988", &hints, &res)))
            errx(1, "%s", gai_strerror(error));

    if ((s = socket(res->ai_family, res->ai_socktype, 0)) < 0)
            err(1, "socket");

    while ((ch = fgetc(stdin)) != EOF)
            sendto(s, &ch, 1, 0, res->ai_addr, res->ai_addrlen);
}

And running something like : dmesg | ./client will use the same address until the program exits. However, when you run it again, the port is different.

So is it the socket function that choose a port? Or the system? Is it sure that the port will still be the same during the client lifetime?

1

1 Answers

5
votes

If the socket is not explicitly bound, then the OS will bind it (with a random port) when you send the first packet. This binding will be active as long as the socket is open, once it's closed the socket is (of course) unbound.

And due to the connectionless nature of UDP sockets, the "server" (if done correctly) should not keep the address of all "clients" that send to it indefinitely. Instead it should use the source address as received in the recvfrom call, and use that for a reply. The only reason to store the source address for more than just a simple request/response, is if you have a more advanced protocol on top of UDP with your own "connection" handling.