10
10
from epsilon.pending import PendingEvent
12
from twisted.python.failure import Failure
12
13
from twisted.internet import protocol, error, reactor, defer
13
14
from twisted.internet.main import CONNECTION_DONE
14
15
from twisted.python import log, util
831
832
self.pseudoPeerPort)
833
834
class PTCP(protocol.DatagramProtocol):
836
L{PTCP} implements a strongly TCP-like protocol on top of UDP. It
837
provides a transport which is connection-oriented, streaming,
838
ordered, and reliable.
840
@ivar factory: A L{ServerFactory} which is used to create
841
L{IProtocol} providers whenever a new PTCP connection is made
844
@ivar _connections: A mapping of endpoint addresses to connection
845
objects. These are the active connections being multiplexed
846
over this UDP port. Many PTCP connections may run over the
847
same L{PTCP} instance, communicating with many different
848
remote hosts as well as multiplexing different PTCP
849
connections to the same remote host. The mapping keys,
850
endpoint addresses, are three-tuples of:
852
- The destination pseudo-port which is always C{1}
853
- The source pseudo-port
854
- A (host, port) tuple giving the UDP address of a PTCP
855
peer holding the other side of the connection
857
The mapping values, connection objects, are L{PTCPConnection}
859
@type _connections: C{dict}
836
864
def __init__(self, factory):
837
865
self.factory = factory
838
866
self._allConnectionsClosed = PendingEvent()
840
869
def connect(self, factory, host, port, pseudoPort=1):
871
Attempt to establish a new connection via PTCP to the given
874
@param factory: A L{ClientFactory} which will be used to
875
create an L{IProtocol} provider if the connection is
876
successfully set up, or which will have failure callbacks
877
invoked on it otherwise.
879
@param host: The IP address of another listening PTCP port to
883
@param port: The port number of that other listening PTCP port
887
@param pseudoPort: Not really implemented. Do not pass a
888
value for this parameter or things will break.
890
@return: A L{PTCPConnection} instance representing the new
891
connection, but you really shouldn't use this for
892
anything. Write a protocol!
841
894
sourcePseudoPort = genConnID() % MAX_PSEUDO_PORT
842
895
conn = self._connections[(pseudoPort, sourcePseudoPort, (host, port))
843
896
] = PTCPConnection(