You wrote,
The real problem is that udp offers a 'connect' but no 'accept'
, but no, the real problem is that UDP is not a connection-oriented protocol. As the POSIX specifications for connect()
explain:
If the initiating socket is not connection-mode, then connect()
shall
set the socket's peer address, and no connection is made. For
SOCK_DGRAM sockets, the peer address identifies where all datagrams
are sent on subsequent send()
functions, and limits the remote sender
for subsequent recv()
functions. [...] Note that despite
no connection being made, the term ``connected'' is used to describe a
connectionless-mode socket for which a peer address has been set.
UDP, again, is not a connection-mode protocol. In particular, it is a datagram protocol. If you want a pair of sockets that each have the other set as their peer then you must use connect()
on both sides. There is no concept of a server socket for datagrams, in the sense of a factory for connected sockets, and even with a peer set, a UDP socket can still communicate with other endpoints.
If you want to emulate a server socket with UDP, then you need to start with a socket listening on a well-known port. Clients will send a message to that port, and expect the server to establish a new, separate socket on a different port for its end of the pseudo-connection. The server would respond from that socket to tell the client which port it is listening on.
You would want to use the contents of these initial messages to confirm each side's intent and to ensure that the server's initial response is correctly paired with with the intended "connection request". For example, perhaps the client's initial message is "CONNECT <PER-CONNECTION-UUID>", and server's initial response is "ACCEPTED <CLIENTS-CONNECTION-UUID>". The keywords in each confirm the intent of the messages, and matching UUIDs (or some other key) allow the client to match the server response with the right connection request.
You must also be aware that UDP is an unreliable protocol, however, and you must be prepared to accommodate that. UDP datagrams can be dropped or lost, and they can be received in a different order than they were sent. This is part of how it achieves better throughput than TCP. If you need to overcome those characteristics then you could do so by implementing own higher-level protocol on top of UDP, but at that point you are probably worse off than if you had just used TCP in the first place.