Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

UDP reads/writes

1 view
Skip to first unread message

pk

unread,
Sep 4, 2008, 4:27:28 PM9/4/08
to
Suppose I have an app that does a single 3000 bytes write to a descriptor
representing an UDP socket.
Now I know UDP is unreliable. My question is: if there is another process
that is doing a read() at the other end of the connection, reading the data
into a 3000 bytes buffer, how many bytes of the 3000 sent by the sender
might that process have read when its read() returns? only either 0 or
3000, or also any number in between? (I guess the answer is the latter, but
I want to confirm that).

Thanks

Jim Logajan

unread,
Sep 4, 2008, 4:54:24 PM9/4/08
to

If the read buffer is 3000 bytes or larger and the read is not interrupted,
then a non-blocking read should return either 3000 or a negative number,
indicating an error (such as EAGAIN on Unix systems.) I believe the read
might also return 0 under certain circumstances (other than due to an
interrupt.) For example, if another thread on the same process closes the
socket.

You shouldn't see any return value "in between" when using a large enough
buffer.

A 3000 byte UDP datagram will, on most networks, get fragmented but that
fragmentation should never appear at the application layer.

pk

unread,
Sep 4, 2008, 5:28:09 PM9/4/08
to

Thanks. It's true that a single UDP datagram is carried in a single IP
packet (which might be fragmented though), so yes, "3000 or nothing" makes
sense.

My question comes from an experiment that I'm doing using Linux tun/tap
interfaces connected between two hosts using UDP. I have my userland
program that reads data from the local tun interface (1 IP packet or 1
ethernet frame at a time) and sends it to the other end of the tunnel using
UDP. At the other end, there is a similar program that reads the data and
sends it to its local tun interface, where the OS will send it to the
appropriate application.
In essence, each UDP datagram that I send over the tunnel contains one IP
packet or one ethernet frame (depending on whether I use tun or tap). So I
want to make certain that the other end either gets the whole UDP datagram
(with the included IP packet or frame) *in a single read*, or it gets
nothing.

What you say seems to configrm that it can indeed be done.

Thanks

Jim Logajan

unread,
Sep 4, 2008, 5:53:04 PM9/4/08
to
pk <p...@pk.invalid> wrote:
> My question comes from an experiment that I'm doing using Linux
> tun/tap interfaces connected between two hosts using UDP. I have my
> userland program that reads data from the local tun interface (1 IP
> packet or 1 ethernet frame at a time) and sends it to the other end of
> the tunnel using UDP. At the other end, there is a similar program
> that reads the data and sends it to its local tun interface, where the
> OS will send it to the appropriate application.
> In essence, each UDP datagram that I send over the tunnel contains one
> IP packet or one ethernet frame (depending on whether I use tun or
> tap). So I want to make certain that the other end either gets the
> whole UDP datagram (with the included IP packet or frame) *in a single
> read*, or it gets nothing.

I would suggest you read the man pages for the recv()/recvfrom()/recvmsg()
calls since one of those may be more appropriate than using read() for your
intended application. Plus, the man page info on those excludes non-
relevant info that appears in read() that may add needless confusion when
figuring out their behavior. Also, to make sure you see the Posix and Linux
man pages for those system calls I recommend using the "-a" option; e.g.:

man -a recv
man -a recvfrom

pk

unread,
Sep 5, 2008, 3:33:14 AM9/5/08
to
On Thursday 4 September 2008 23:53, Jim Logajan wrote:

> I would suggest you read the man pages for the recv()/recvfrom()/recvmsg()
> calls since one of those may be more appropriate than using read() for
> your intended application.

Yes, sorry. I'm already using sendto() and recvfrom(). When I said "read" I
meant it in a generic sense, although re-reading the messages I realize
that in the first one I erroneously used read(), giving the impression that
I was talking about the actual function.

Thanks again.

Jorgen Grahn

unread,
Sep 6, 2008, 2:18:49 PM9/6/08
to
On Thu, 04 Sep 2008 15:54:24 -0500, Jim Logajan <Jam...@Lugoj.com> wrote:
...

> If the read buffer is 3000 bytes or larger and the read is not interrupted,
> then a non-blocking read should return either 3000 or a negative number,
> indicating an error (such as EAGAIN on Unix systems.) I believe the read
> might also return 0 under certain circumstances (other than due to an
> interrupt.) For example, if another thread on the same process closes the
> socket.
>
> You shouldn't see any return value "in between" when using a large enough
> buffer.

And using the right system call, you can be told "tough luck, you
should have been a bigger buffer" (MSGTRUNC or something). If you
don't explicitly ask for this and the buffer is too small, you may get
a truncated datagram, which is often worse than nothing. Been there,
done that ...

/Jorgen

--
// Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
\X/ snipabacken.se> R'lyeh wgah'nagl fhtagn!

0 new messages