You use the sendto() function to send data from one socket to another socket:
sendto(s, buf, buflen, flags, &to, tolen);
You use the s, buf, buflen and flags parameters in exactly the same way as with connectionoriented sockets. You pass the destination address with to and the length of the address with tolen.
Please note that reliable data transfer cannot be guaranteed when using a datagram interface. This means that a sendto() call can only return error information if the local system is aware of the fact that a message could not be transferred.
You use the recvfrom() function to receive a message on a datagram socket:
recvfrom(s, buf, buflen, flags, &from, &fromlen);
The fromlen parameter initially contains the size of the from buffer. On return from the recvfrom() function, fromlen specifies the size of the address of the socket from which the datagram was received.
If you wish, you can define a specific destination address for a datagram socket before a sendto() or recvfrom() call with connect(). In this case, calling sendto() or recvfrom() results in the following behavior:
Data which the task sends with sendto() without explicitly specifying a destination address is sent automatically to the partner with the destination address specified in the connect() call.
A user task only receives data with recvfrom() from the partner with the address specified in the connect() call.
For a datagram socket, only one target address can be specified with connect() at any one time. However, you can define a different destination address for the socket with an additional connect() call.
A connect() call for a datagram socket returns immediately, and the system only stores the address of the communications partner.