39
from main import CONNECTION_LOST, CONNECTION_DONE
42
class Connection(abstract.FileDescriptor,
45
"""This is a UDP virtual connection
47
This transport connects to a given host/port over UDP. By nature
48
of UDP, only outgoing communications are allowed. If a connection
49
is initiated by a packet arriving at a UDP port, it is up to the
50
port to call dataReceived with that packet. By default, once data
51
is written once to the connection, it is lost.
56
def __init__(self, skt, protocol, remote, local, sessionno):
58
self.fileno = skt.fileno
60
self.protocol = protocol
62
self.sessionno = sessionno
64
self.logstr = "%s,%s,%s (UDP)" % (self.protocol.__class__.__name__, sessionno, self.remote[0])
67
res = abstract.FileDescriptor.write(self,data)
68
if not self.keepConnection:
72
def writeSomeData(self, data):
73
"""Connection.writeSomeData(data) -> #of bytes written | CONNECTION_LOST
74
This writes as much data as possible to the socket and returns either
75
the number of bytes read (which is positive) or a connection error code
80
return self.socket.sendto(data, self.remote)
81
except socket.error, se:
82
if se.args[0] == EWOULDBLOCK:
84
return CONNECTION_LOST
88
def connectionLost(self):
89
"""See abstract.FileDescriptor.connectionLost().
91
protocol = self.protocol
93
abstract.FileDescriptor.connectionLost(self)
97
protocol.connectionLost()
100
"""Return the prefix to log with when I own the logging thread.
106
Returns a tuple of ('INET_UDP', hostname, port), indicating
107
the connected client's address
109
return ('INET_UDP',)+self.remote
113
Returns a tuple of ('INET_UDP', hostname, port), indicating
116
return ('INET_UDP',)+self.socket.getsockname()
35
119
class Port(abstract.FileDescriptor):
36
120
"""I am a UDP server port, listening for packets.
38
122
When a packet is received, I will call my factory's packetReceived
39
123
with the packet and an address.
42
def __init__(self, port, factory, maxPacketSize=8192):
128
def __init__(self, port, factory, interface='', maxPacketSize=8192):
43
129
"""Initialize with a numeric port to listen on.
46
132
self.factory = factory
47
133
self.maxPacketSize = maxPacketSize
134
self.interface = interface
49
137
def __repr__(self):
50
138
return "<%s on %s>" % (self.factory.__class__, self.port)
76
164
log.msg("%s starting on %s"%(self.factory.__class__, self.port))
77
165
skt = self.createInternetSocket()
78
skt.bind( ('',self.port) )
166
skt.bind( (self.interface ,self.port) )
79
167
self.connected = 1
81
169
self.fileno = self.socket.fileno
82
170
self.startReading()
172
def createConnection(self, addr):
173
"""Creates a virtual connection over UDP"""
175
protocol = self.factory.buildProtocol(addr)
178
transport = Connection(self.socket.dup(), protocol, addr, self, s)
179
protocol.makeConnection(transport, self)
181
traceback.print_exc(file=log.logfile)
85
185
"""Called when my socket is ready for reading.
87
This gets a packet and calls the factory's packetReceived
187
This reads a packet, calls self.protocol() to handle it.
91
190
data, addr = self.socket.recvfrom(self.maxPacketSize)
92
self.factory.packetReceived(data, addr, self)
191
transport = self.createConnection(addr)
192
# Ugly patch needed because logically control passes here
193
# from the port to the transport.
194
self.logstr = transport.logPrefix()
195
transport.protocol.dataReceived(data)
94
198
traceback.print_exc(file=log.logfile)