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, 鈥?
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.
|