On Sep 30, 10:48 am, Spoon <root@localhost> wrote:
> Rainer Weikusat wrote:
> > Spoon wrote:
>
> >> Consider an internet datagram socket.
> >> sock = socket(PF_INET, SOCK_DGRAM, 0);
>
> >> It seems wasteful to make one system call per datagram I'm about to
> >> recv(). On the other hand, the overhead from the system calls might be
> >> negligible.
>
> >> I think I could write:
>
> >> uint8_t buf[PACKET_SIZE*N];
> >> struct iovec iov;
>
> Doh! I meant struct iovec iov[N];
>
> >> for (int i=0; i < N; ++i)
> >> {
> >> iov[i].iov_base = buf + PACKET_SIZE*i;
> >> iov[i].iov_len = PACKET_SIZE;
> >> }
>
> >> then call recvmsg().
>
> >> If I do set MSG_DONTWAIT, and if there are 0<K<N datagrams available,
> >> will recvmsg return PACKET_SIZE*K with errno unchanged?
>
> > No. Datagram sockets preserve message boundaries, and this means that
> > each call to a receive-routine will return exactly one message (in
> > absence of errors).
>
> If I understand correctly, recvmsg() could be used to "splice" a single
> large datagram into several parts (one part per struct iovec). But it
> can't be used to receive more than one datagram?
>
> If this is correct, my question becomes: Is there a way to receive more
> than one datagram in a single system call?
No (that is, not without introducing new syscall in the kernel).
But if you change UDP to TCP, you get the desired property
automatically.
Did you actually measure the overhead of the recv() syscall to begin
with ?
Yakov
|