Unix Network Programming, Volume 1: The Sockets Networking API (3rd Edition)

14.4 readv and writev Functions

These two functions are similar to read and write , but readv and writev let us read into or write from one or more buffers with a single function call. These operations are called scatter read (since the input data is scattered into multiple application buffers) and gather write (since multiple buffers are gathered for a single output operation).

#include <sys/uio.h>

ssize_t readv(int filedes , const struct iovec * iov , int iovcnt ) ;

ssize_t writev(int filedes , const struct iovec * iov , int iovcnt ) ;

Both return: number of bytes read or written, “1 on error

The second argument to both functions is a pointer to an array of iovec structures, which is defined by including the <sys/uio.h> header.

struct iovec { void *iov_base; /* starting address of buffer */ size_t iov_len; /* size of buffer */ };

The datatypes shown for the members of the iovec structure are those specified by POSIX. You may encounter implementations that define iov_base to be a char * , and iov_len to be an int .

There is some limit to the number of elements in the array of iovec structures that an implementation allows. Linux, for example, allows up to 1,024, while HP-UX has a limit of 2,100. POSIX requires that the constant IOV_MAX be defined by including the <sys/uio.h> header and that its value be at least 16.

The readv and writev functions can be used with any descriptor, not just sockets. Also, writev is an atomic operation. For a record-based protocol such as UDP, one call to writev generates a single UDP datagram.

We mentioned one use of writev with the TCP_NODELAY socket option in Section 7.9. We said that a write of 4 bytes followed by a write of 396 bytes could invoke the Nagle algorithm and a preferred solution is to call writev for the two buffers.

Категории