Sending and Receiving Data (datagram sockets)

Data transmission on datagram sockets is significantly different from stream sockets. The most important difference is that transmission is not reliable on datagram sockets. This means that if an application attempts to send data to another application, the system does nothing to guarantee that the data will actually be delivered to the remote application. Reliability will tend to be good on LANs (local-area networks, such as a network connecting several computers within a single building), but can be very poor on WANs (wide-area networks, such as the Internet which connects hundreds of thousands of computers worldwide).

The next important difference in datagram sockets is that they are connectionless. This means that there is no default remote address assigned to them. For this reason, an application which wants to send data must specify the address to which the data is destined with the sendto() API. In addition, an application typically wants to know where data came from, so it receives data with the recvfrom() API, which returns the address of the sender of the data.

The final significant difference in data transmission for datagram sockets is that it is "message oriented." This means that there is a one-to-one correspondence between sendto() and recvfrom() calls, and that the system does not coalesce data when sending it. For example, if an application makes 10 calls to sendto() with a buffer of two bytes, the remote application will need to perform 10 calls to recvfrom() with a buffer of at least two bytes to receive all the data.

Below is a code fragment from a datagram sockets application which echos datagrams back to the sender.


 
SOCKET             s;
SOCKADDR_IN         remoteAddr;
int             remoteAddrLength = sizeof(remoteAddr);
BYTE             buffer[1024];
int             bytesReceived;

for ( ; ; ) {       
    /* Receive a datagram on socket s */

   bytesReceived = recvfrom( s, buffer, sizeof(buffer),0,
                        (PSOCKADDR)&remoteAddr, &remoteAddrLength );
  
    /* Echo back to the server as long as bytes were received */

   if ( bytesReceived != SOCKET_ERROR ||
        sendto( s, buffer, bytesRecieved, 0,
                (PSOCKADDR)&remoteAddr, remoteAddrLength ) ==
        SOCKET_ERROR ){
        sprintf(buf,"Windows Sockets error %d: Error while sending data.",
             WSAGetLastError());
        MessageBox (hWnd,buf,"Windows Sockets Error",MB_OK);    
        shutdown_appl();
    }
}

As mentioned earlier, it is possible to connect() a datagram socket. Once a datagram socket is connected, all data is sent and received from the remote address to which the datagram is connected, so it is possible to use the send() and recv() APIs on connected datagram sockets.