Difference Between send and sendto in C UDP

In C socket programming, both send() and sendto() are system calls used to transmit data across a network, but they handle destination addressing differently when using the User Datagram Protocol (UDP). This article explains the technical distinctions between sendto() and send(), how calling connect() alters UDP socket behavior, and the appropriate scenarios for using each function.

Core Difference: Destination Address Handling

UDP is inherently a connectionless protocol, meaning individual datagrams can be routed to different destinations independently. The core distinction between send() and sendto() revolves around how the target address is supplied to the operating system kernel:

Function Signatures Comparison

The difference is reflected in the standard POSIX prototypes:

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
               const struct sockaddr *dest_addr, socklen_t addrlen);

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

The sendto() function includes dest_addr and addrlen to define the target network endpoint for that specific datagram. Calling sendto() with a NULL destination address and zero addrlen is functionally identical to calling send().

Using send() with UDP

To use send() with a UDP socket, the socket must first be associated with a remote address using the connect() system call.

Unlike TCP, calling connect() on a UDP socket does not initiate a network handshake. Instead, it is purely a local operation that stores the remote IP address and port inside the operating system’s socket data structure. Once connected:

When to Use sendto()

When to Use send()