Sending data with TCP requires calling connect() to set the remote address and establish the TCP connection. Thus, we use send() with TCP sockets, as shown in the following code:
connect(tcp_socket, peer_address, peer_address_length);
send(tcp_socket, data, data_length, 0);
UDP is a connectionless protocol. Therefore, no connection is established before sending data. A UDP connection is never established. With UDP, data is simply sent and received. We can call connect() and then send(), as we mentioned previously, but the socket API provides an easier way for UDP sockets in the form of the sendto() function. It works like this:
sendto(udp_socket, data, data_length, 0,
peer_address, peer_address_length);
connect() on a UDP socket works a bit differently. All connect() does with a UDP socket is associate a remote address. Thus, while connect() on a TCP socket involves a handshake for sending packets over the network, connect() on a UDP socket only stores an address locally.
So, a UDP client can be structured in two different ways, depending on whether you use connect(), send(), and recv(), or instead use sendto() and recvfrom().
The following diagram compares the program flow of a TCP Client to a UDP Client using either method:
Note that, while using connect(), the UDP Client only receives data from the peer having the IP address and the port that is given to connect(). However, when not using connect(), the recvfrom() function returns data from any peer that addresses us! Of course, that peer would need to know our address and port. Unless we call bind(), our local address and port is assigned automatically by the operating system.