Networking Forums

Networking Forums > Computer Networking > Linux Networking > Grabbing several datagrams from a socket

Reply
Thread Tools Display Modes

Grabbing several datagrams from a socket

 
 
Spoon
Guest
Posts: n/a

 
      09-28-2007, 11:32 AM
Hello everyone,

Consider an internet datagram socket.
sock = socket(PF_INET, SOCK_DGRAM, 0);

Suppose I know there are more than one datagram waiting in the socket.
(For example, because I'm receiving 4000 packets per second, and I've
just woken up from a 10 ms sleep.)

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;
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 don't set MSG_DONTWAIT, will recvmsg() block until N packets are
available?

If I do set MSG_DONTWAIT, and if there are 0 datagrams available, will
recvmsg return -1 with errno set to EAGAIN?

If I do set MSG_DONTWAIT, and if there are 0<K<N datagrams available,
will recvmsg return PACKET_SIZE*K with errno unchanged?

Final question: has anyone measured the overhead of calling recv() 10
times in a loop vs calling recvmsg() to greb 10 packets?

(My OS is Linux 2.6.22 if it matters.)

Regards.
 
Reply With Quote
 
 
 
 
Rainer Weikusat
Guest
Posts: n/a

 
      09-28-2007, 01:18 PM
Spoon <root@localhost> writes:
> 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;
> 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).
 
Reply With Quote
 
Spoon
Guest
Posts: n/a

 
      09-30-2007, 08:48 AM
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?

Regards.
 
Reply With Quote
 
Yakov
Guest
Posts: n/a

 
      09-30-2007, 10:47 AM
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

 
Reply With Quote
 
Rainer Weikusat
Guest
Posts: n/a

 
      09-30-2007, 04:12 PM
Yakov <(E-Mail Removed)> writes:
> On Sep 30, 10:48 am, Spoon <root@localhost> wrote:
>> Rainer Weikusat wrote:


[...]

>> 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.


TCP is bytestream protocol, consequently, there is not way to 'receive
a datagram' with TCP. A successful receive will return some number of
bytes between zero (remote closed the connection) and the size of the
buffer which was passed to the syscall. Additionally, it is a reliable
protocol, which is not useful for realtime-applications (which I
figure 'Spoon' is writing about), because the data becomes useless
once the time when it would have been needed has passed (imagine a
local 10s power outage at some place where a router forwarding
telephone voice data sits: If data from this period is afterwards
retransmitted, the receiver would be ten seconds in the past relative
to the sender afterwards).
 
Reply With Quote
 
 
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Trouble sending UDP datagrams on Win2008 VB Windows Networking 0 02-12-2009 09:07 PM
Laptop keeps grabbing wrong wireless network Daisy Wireless Networks 4 12-30-2008 11:56 AM
device grabbing IP Cindy B Windows Networking 2 03-06-2008 08:18 AM
Deleting all the datagrams in a socket Spoon Linux Networking 4 09-29-2007 04:26 AM
WLAN Monitor 10038 Socket operation on non-socket Bill Windows Networking 1 03-01-2004 10:34 PM



1 2 3 4 5 6 7 8 9 10 11