If you are using multicast or broadcast UDP communication, then it often makes sense to bind multiple programs to the same UDP port, and it is possible to do so if you call setsockopt()
with the appropriate arguments before calling bind()
on it:
const int trueValue = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &trueValue, sizeof(trueValue));
#ifdef __APPLE__
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &trueValue, sizeof(trueValue));
#endif
In that scenario, a copy of every multicast/broadcast UDP packet received on the port will be delivered to each of the sockets bound to that port (which is roughly the same behavior you would get if each program was running on a separate machine, and therefore usually what you want)
OTOH, if you are sending only unicast UDP packets (i.e. packets that are intended to go to a single recipient) then it's usually not useful to bind multiple programs to the same port, as each UDP packet you send will be received by exactly one receiving program and with multiple programs listening to the same port, it's unspecified/unpredictable which program that will be. In your case, for example, your client program might send a packet and the server wouldn't receive it because the packet has been queued into the client's socket's buffer instead. So for that case you're better off having the client and server bind to different ports. (Keep in mind that any program that receives a UDP packet can easily find out what port the packet's sender is bound to, by calling recvfrom()
to receive the packet and looking at the contents of the address
argument afterwards; therefore it should be straightforward for the server to reply to packets sent to it by the client, even if the client uses a completely random/arbitrary UDP port every time it runs. If you tell your client to bind()
to port 0, the networking stack will pick a currently-available UDP port for it to bind to)