When doing async socket IO with epoll on non-blocking sockets, reading seems straightforward: Just epoll_wait
until the socket is ready for reading, and read until you get EAGAIN
/EWOULDBLOCK
.
But how do you send? Presumably doing a single large send
operation would block, so you will always get EAGAIN
/EWOULDBLOCK
. What are you meant to do?
Presumably the kernel will not be able to send all data right away, that's why send
on success returns the number of bytes sent. The important thing is that the number returned can (and most likely will) be lower than the total length specified in the call. You will only get EAGAIN/EWOULDBLOCK
as an answer if no bytes at all can be sent. So when sending a large amount of data, you just need to correctly handle the (very likely) possibility that not all data is sent at once.
Note: this is different for datagram (UDP) sockets, since partial datagrams cannot be sent. See POSIX: Return value from write() on UDP socket for more information.
Here's an example assuming a SOCK_STREAM
(TCP) socket:
size_t len;
size_t sent;
char *buf;
/* ... prepare data ... */
while (sent < len) {
ssize_t n;
if ((n = send(sockfd, buf + sent, len - sent, flags)) == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK)
continue;
perror("send failed");
exit(1);
}
sent += n;
}