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