Can't get UDP example to work
Roy Smith
roy at panix.com
Sun Jul 26 16:31:43 EDT 2009
In article
<2f578124-1ae3-45a5-a0c9-b8b05c0b5d3a at p23g2000vbl.googlegroups.com>,
Paul Barry <pauljbarry3 at gmail.com> wrote:
> In this case, I think he's trying to illustrate how the UDP example
> compares to the TCP example from the previous section, which is why he
> choose to keep the methods the same.
I suppose, but I still think that's a confusing way to teach the
differences between UDP and TCP. The fundamental differences are:
1) TCP makes sure what you send gets there (for reasonably large values of
"makes sure"). UDP just tosses stuff out onto the network and hopes for
the best.
2) TCP is connection-oriented. Connections must be explicitly set up
before any data can flow, and once two sockets are connected, they can
never be disconnected (short of tearing down the connection and starting
again with two new sockets). With UPD, every time you send data, you have
to specify where it's going, and a given socket can be talking to many
different remote endpoints on a packet-by-packet basis.
3) TCP is a stream protocol, which hides record boundaries; it is free to
combine and/or split up your data into whatever packet boundaries it wants,
and there is no way for the receiving end to discover where the boundaries
are. UDP, on the other hand, honors record boundaries; there is a
one-to-one correspondence between each write (send, sendto) call at one and
each read (recv, recvfrom) call at the other.
It's difficult to demonstrate #1 in a simple example, so I'll skip that.
But, #2 and #3 are easy.
The example you gave uses connect() on a UDP socket. That's not pointing
out the differences between UDP and TCP, that's hiding them behind a
strange corner of the API. There really is no connection set up when you
do connect() on a UDP socket; it's just a way of saying, "From now on, I'm
going to skip telling you the destination of each individual datagram.
Just use this destination from now on". It saves moving a bit of data
around, but it's not fundamentally a connection.
As for the stream/datagram distinction, sendall() is very much a stream
creature. It says, "Just keep banging out packets until you've managed to
transmit the whole buffer". That only makes sense in an environment where
packet boundaries are meaningless. Using it with UDP is sort of like
saying, "Use as many packets as it takes, as long as that number is one".
It's not not a concept that makes sense in a datagram world. That it works
at all on UDP is (IHMO) a mis-guided attempt at interface uniformity.
If I were writing an example on how to use UDP, I would leave out the
connect() call, and use sendto() instead of sendall(). Once the student
has those down, that's the time to talk about weird corner cases like how
connect() and sendall() can be twisted to work with UDP sockets. Or maybe
not even bother.
More information about the Python-list
mailing list