UDP Networking

Overview

Unlike TCP, UDP has no notion of connections. A UDP socket can receive datagrams from any server on the network, and send datagrams to any host on the network. In addition, datagrams may arrive in any order, never arrive at all, or be duplicated in transit.

Since there are no multiple connections, we only use a single object, a protocol, for each UDP socket. We then use the reactor to connect this protocol to a UDP transport, using the twisted.internet.interfaces.IReactorUDP reactor API.

DatagramProtocol

At the base, the place where you actually implement the protocol parsing and handling, is the DatagramProtocol class. This class will usually be decended from twisted.internet.protocol.DatagramProtocol. Most protocol handlers inherit either from this class or from one of its convenience children. The DatagramProtocol class receives datagrams, and can send them out over the network. Received datagrams include the address they were sent from, and when sending datagrams the address to send to must be specified.

Here is a simple example:

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor

class Echo(DatagramProtocol):
    
    def datagramReceived(self, data, (host, port)):
        print "received %r from %s:%d" % (data, host, port)
        self.transport.write(data, (host, port))

reactor.listenUDP(9999, Echo())
reactor.run()
    

As you can see, the protocol is registed with the reactor. This means it may be persisted if it's added to an application, and thus it has twisted.internet.protocol.DatagramProtocol.startProtocol and twisted.internet.protocol.DatagramProtocol.stopProtocol methods that will get called when the protocol is connected and disconnected from a UDP socket.

The protocol's transport attribute will implement the twisted.internet.interfaces.IUDPTransport interface.

Connected UDP

A connected UDP socket is slighly different from a standard one - it can only send and receive datagramss to/from a single address, but this does not in any way imply a connection. Datagrams may still arrive in any order, and the port on the other side may have no one listening. The benefit of the connected UDP socket is that it is faster.

Unlike a regular UDP protocol, we do not need to specify where to send datagrams to, and are not told where they came from since they can only come from address the socket is 'connected' to.

The protocol's transport attribute will implement the twisted.internet.interfaces.IUDPConnectedTransport interface.

from twisted.internet.protocol import ConnectedDatagramProtocol
from twisted.internet import reactor

class Echo(ConnectedDatagramProtocol):
    
    def datagramReceived(self, data):
        self.transport.write(data)

reactor.connectUDP("www.example.com", 9999, Echo())
reactor.run()