You use the sendto() function to send data from one socket to another socket:
sendto(s, buf, buflen, flags, (struct sockaddr *)&to, tolen);
You use the s, buf, buflen and flags parameters in exactly the same way as with connection-oriented sockets. You pass the destination address with to and the length of the address with tolen. The sender is not informed of any errors when a datagram socket is used. If the system has the information locally that a message cannot be transferred (e.g. if a network cannot be reached), then the sendto() call returns the value -1 and the global errno variable contains the appropriate error code.
You use the recvfrom() function to receive a message over a datagram socket:
recvfrom(s, buf, buflen, flags, (struct sockaddr *)&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 process 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 process 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 another connect() call.
A connect() call for a datagram socket returns immediately. The system only stores the address of the communications partner.