Python twisted.internet.reactor.listenTCP() Examples

The following are 30 code examples of twisted.internet.reactor.listenTCP(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module twisted.internet.reactor , or try the search function .
Example #1
Source File: test_tcp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 6 votes vote down vote up
def test_cannotBind(self):
        """
        L{IReactorTCP.listenTCP} raises L{error.CannotListenError} if the
        address to listen on is already in use.
        """
        f = MyServerFactory()

        p1 = reactor.listenTCP(0, f, interface='127.0.0.1')
        self.addCleanup(p1.stopListening)
        n = p1.getHost().port
        dest = p1.getHost()
        self.assertEqual(dest.type, "TCP")
        self.assertEqual(dest.host, "127.0.0.1")
        self.assertEqual(dest.port, n)

        # make sure new listen raises error
        self.assertRaises(error.CannotListenError,
                          reactor.listenTCP, n, f, interface='127.0.0.1') 
Example #2
Source File: test_tcp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 6 votes vote down vote up
def test_directConnectionLostCall(self):
        """
        If C{connectionLost} is called directly on a port object, it succeeds
        (and doesn't expect the presence of a C{deferred} attribute).

        C{connectionLost} is called by L{reactor.disconnectAll} at shutdown.
        """
        serverFactory = MyServerFactory()
        port = reactor.listenTCP(0, serverFactory, interface="127.0.0.1")
        portNumber = port.getHost().port
        port.connectionLost(None)

        client = MyClientFactory()
        serverFactory.protocolConnectionMade = defer.Deferred()
        client.protocolConnectionMade = defer.Deferred()
        reactor.connectTCP("127.0.0.1", portNumber, client)
        def check(ign):
            client.reason.trap(error.ConnectionRefusedError)
        return client.failDeferred.addCallback(check) 
Example #3
Source File: http.py    From kotori with GNU Affero General Public License v3.0 6 votes vote down vote up
def startService(self):
        """
        Start TCP listener on designated HTTP port,
        serving ``HttpChannelContainer`` as root resource.
        """

        # Don't start service twice
        if self.running == 1:
            return

        self.running = 1

        # Prepare startup
        http_listen = self.settings.kotori.http_listen
        http_port   = int(self.settings.kotori.http_port)
        log.info('Starting HTTP service on {http_listen}:{http_port}', http_listen=http_listen, http_port=http_port)

        # Configure root Site object and start listening to requests.
        # This must take place only once - can't bind to the same port multiple times!
        factory = LocalSite(self.root)
        reactor.listenTCP(http_port, factory, interface=http_listen) 
Example #4
Source File: tkconch.py    From Safejumper-for-Desktop with GNU General Public License v2.0 6 votes vote down vote up
def serviceStarted(self):
        if not options['noshell']:
            self.openChannel(SSHSession())
        if options.localForwards:
            for localPort, hostport in options.localForwards:
                reactor.listenTCP(localPort,
                            forwarding.SSHListenForwardingFactory(self,
                                hostport,
                                forwarding.SSHListenClientForwardingChannel))
        if options.remoteForwards:
            for remotePort, hostport in options.remoteForwards:
                log.msg('asking for remote forwarding for %s:%s' %
                        (remotePort, hostport))
                data = forwarding.packGlobal_tcpip_forward(
                    ('0.0.0.0', remotePort))
                self.sendGlobalRequest('tcpip-forward', data)
                self.remoteForwards[remotePort] = hostport 
Example #5
Source File: server.py    From kotori with GNU Affero General Public License v3.0 6 votes vote down vote up
def boot_frontend(config, debug=False):
    """
    Boot a Pyramid WSGI application as Twisted component
    """

    http_port = int(config.get('config-web', 'http_port'))
    websocket_uri = unicode(config.get('wamp', 'listen'))

    # https://stackoverflow.com/questions/13122519/serving-pyramid-application-using-twistd/13138610#13138610
    config = resource_filename('kotori.frontend', 'development.ini')
    application = get_app(config, 'main')

    # https://twistedmatrix.com/documents/13.1.0/web/howto/web-in-60/wsgi.html
    resource = WSGIResource(reactor, reactor.getThreadPool(), application)

    reactor.listenTCP(http_port, Site(resource)) 
Example #6
Source File: test_tcp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 6 votes vote down vote up
def test_closePortInProtocolFactory(self):
        """
        A port created with L{IReactorTCP.listenTCP} can be connected to with
        L{IReactorTCP.connectTCP}.
        """
        f = ClosingFactory()
        port = reactor.listenTCP(0, f, interface="127.0.0.1")
        f.port = port
        self.addCleanup(f.cleanUp)
        portNumber = port.getHost().port
        clientF = MyClientFactory()
        reactor.connectTCP("127.0.0.1", portNumber, clientF)
        def check(x):
            self.assertTrue(clientF.protocol.made)
            self.assertTrue(port.disconnected)
            clientF.lostReason.trap(error.ConnectionDone)
        return clientF.deferred.addCallback(check) 
Example #7
Source File: test_tcp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 6 votes vote down vote up
def _connectedClientAndServerTest(self, callback):
        """
        Invoke the given callback with a client protocol and a server protocol
        which have been connected to each other.
        """
        serverFactory = MyServerFactory()
        serverConnMade = defer.Deferred()
        serverFactory.protocolConnectionMade = serverConnMade
        port = reactor.listenTCP(0, serverFactory, interface="127.0.0.1")
        self.addCleanup(port.stopListening)

        portNumber = port.getHost().port
        clientF = MyClientFactory()
        clientConnMade = defer.Deferred()
        clientF.protocolConnectionMade = clientConnMade
        reactor.connectTCP("127.0.0.1", portNumber, clientF)

        connsMade = defer.gatherResults([serverConnMade, clientConnMade])
        def connected(result):
            serverProtocol, clientProtocol = result
            callback(serverProtocol, clientProtocol)
            serverProtocol.transport.loseConnection()
            clientProtocol.transport.loseConnection()
        connsMade.addCallback(connected)
        return connsMade 
Example #8
Source File: test_tcp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 6 votes vote down vote up
def test_tcpNoDelay(self):
        """
        The transport of a protocol connected with L{IReactorTCP.connectTCP} or
        L{IReactor.TCP.listenTCP} can have its I{TCP_NODELAY} state inspected
        and manipulated with L{ITCPTransport.getTcpNoDelay} and
        L{ITCPTransport.setTcpNoDelay}.
        """
        def check(serverProtocol, clientProtocol):
            for p in [serverProtocol, clientProtocol]:
                transport = p.transport
                self.assertEqual(transport.getTcpNoDelay(), 0)
                transport.setTcpNoDelay(1)
                self.assertEqual(transport.getTcpNoDelay(), 1)
                transport.setTcpNoDelay(0)
                self.assertEqual(transport.getTcpNoDelay(), 0)
        return self._connectedClientAndServerTest(check) 
Example #9
Source File: test_webclient.py    From Safejumper-for-Desktop with GNU General Public License v2.0 6 votes vote down vote up
def test_getPageDeprecated(self):
        """
        L{client.getPage} is deprecated.
        """
        port = reactor.listenTCP(
            0, server.Site(Data(b'', 'text/plain')), interface="127.0.0.1")
        portno = port.getHost().port
        self.addCleanup(port.stopListening)
        url = networkString("http://127.0.0.1:%d" % (portno,))

        d = client.getPage(url)
        warningInfo = self.flushWarnings([self.test_getPageDeprecated])
        self.assertEqual(len(warningInfo), 1)
        self.assertEqual(warningInfo[0]['category'], DeprecationWarning)
        self.assertEqual(
            warningInfo[0]['message'],
            "twisted.web.client.getPage was deprecated in "
            "Twisted 16.7.0; please use https://pypi.org/project/treq/ or twisted.web.client.Agent instead")

        return d.addErrback(lambda _: None) 
Example #10
Source File: test_webclient.py    From Safejumper-for-Desktop with GNU General Public License v2.0 6 votes vote down vote up
def test_downloadPageDeprecated(self):
        """
        L{client.downloadPage} is deprecated.
        """
        port = reactor.listenTCP(
            0, server.Site(Data(b'', 'text/plain')), interface="127.0.0.1")
        portno = port.getHost().port
        self.addCleanup(port.stopListening)
        url = networkString("http://127.0.0.1:%d" % (portno,))

        path = FilePath(self.mktemp())
        d = client.downloadPage(url, path.path)

        warningInfo = self.flushWarnings([self.test_downloadPageDeprecated])
        self.assertEqual(len(warningInfo), 1)
        self.assertEqual(warningInfo[0]['category'], DeprecationWarning)
        self.assertEqual(
            warningInfo[0]['message'],
            "twisted.web.client.downloadPage was deprecated in "
            "Twisted 16.7.0; please use https://pypi.org/project/treq/ or twisted.web.client.Agent instead")

        return d.addErrback(lambda _: None) 
Example #11
Source File: test_tcp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 6 votes vote down vote up
def test_serverRepr(self):
        """
        Check that the repr string of the server transport get the good port
        number if the server listens on 0.
        """
        server = MyServerFactory()
        serverConnMade = server.protocolConnectionMade = defer.Deferred()
        port = reactor.listenTCP(0, server)
        self.addCleanup(port.stopListening)

        client = MyClientFactory()
        clientConnMade = client.protocolConnectionMade = defer.Deferred()
        connector = reactor.connectTCP("127.0.0.1",
                                       port.getHost().port, client)
        self.addCleanup(connector.disconnect)
        def check(result):
            serverProto, clientProto = result
            portNumber = port.getHost().port
            self.assertEqual(
                repr(serverProto.transport),
                "<AccumulatingProtocol #0 on %s>" % (portNumber,))
            serverProto.transport.loseConnection()
            clientProto.transport.loseConnection()
        return defer.gatherResults([serverConnMade, clientConnMade]
            ).addCallback(check) 
Example #12
Source File: test_distrib.py    From Safejumper-for-Desktop with GNU General Public License v2.0 6 votes vote down vote up
def testDistrib(self):
        # site1 is the publisher
        r1 = resource.Resource()
        r1.putChild("there", static.Data("root", "text/plain"))
        site1 = server.Site(r1)
        self.f1 = PBServerFactory(distrib.ResourcePublisher(site1))
        self.port1 = reactor.listenTCP(0, self.f1)
        self.sub = distrib.ResourceSubscription("127.0.0.1",
                                                self.port1.getHost().port)
        r2 = resource.Resource()
        r2.putChild("here", self.sub)
        f2 = MySite(r2)
        self.port2 = reactor.listenTCP(0, f2)
        agent = client.Agent(reactor)
        d = agent.request(b"GET", "http://127.0.0.1:%d/here/there" % \
                          (self.port2.getHost().port,))
        d.addCallback(client.readBody)
        d.addCallback(self.assertEqual, 'root')
        return d 
Example #13
Source File: test_tcp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 6 votes vote down vote up
def testWriter(self):
        f = protocol.Factory()
        f.protocol = LargeBufferWriterProtocol
        f.done = 0
        f.problem = 0
        f.len = self.datalen
        wrappedF = FireOnCloseFactory(f)
        p = reactor.listenTCP(0, wrappedF, interface="127.0.0.1")
        self.addCleanup(p.stopListening)
        n = p.getHost().port
        clientF = LargeBufferReaderClientFactory()
        wrappedClientF = FireOnCloseFactory(clientF)
        reactor.connectTCP("127.0.0.1", n, wrappedClientF)

        d = defer.gatherResults([wrappedF.deferred, wrappedClientF.deferred])
        def check(ignored):
            self.assertTrue(f.done, "writer didn't finish, it probably died")
            self.assertTrue(clientF.len == self.datalen,
                            "client didn't receive all the data it expected "
                            "(%d != %d)" % (clientF.len, self.datalen))
            self.assertTrue(clientF.done,
                            "client didn't see connection dropped")
        return d.addCallback(check) 
Example #14
Source File: unix.py    From Safejumper-for-Desktop with GNU General Public License v2.0 6 votes vote down vote up
def global_tcpip_forward(self, data):
        hostToBind, portToBind = forwarding.unpackGlobal_tcpip_forward(data)
        from twisted.internet import reactor
        try:
            listener = self._runAsUser(
                reactor.listenTCP, portToBind,
                forwarding.SSHListenForwardingFactory(
                    self.conn,
                    (hostToBind, portToBind),
                    forwarding.SSHListenServerForwardingChannel),
                interface=hostToBind)
        except:
            return 0
        else:
            self.listeners[(hostToBind, portToBind)] = listener
            if portToBind == 0:
                portToBind = listener.getHost()[2]  # The port
                return 1, struct.pack('>L', portToBind)
            else:
                return 1 
Example #15
Source File: test_ssl.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def _runTest(self, clientProto, serverProto, clientIsServer=False):
        """
        Helper method to run TLS tests.

        @param clientProto: protocol instance attached to the client
            connection.
        @param serverProto: protocol instance attached to the server
            connection.
        @param clientIsServer: flag indicated if client should initiate
            startTLS instead of server.

        @return: a L{defer.Deferred} that will fire when both connections are
            lost.
        """
        self.clientProto = clientProto
        cf = self.clientFactory = protocol.ClientFactory()
        cf.protocol = lambda: clientProto
        if clientIsServer:
            cf.server = False
        else:
            cf.client = True

        self.serverProto = serverProto
        sf = self.serverFactory = protocol.ServerFactory()
        sf.protocol = lambda: serverProto
        if clientIsServer:
            sf.client = False
        else:
            sf.server = True

        port = reactor.listenTCP(0, sf, interface="127.0.0.1")
        self.addCleanup(port.stopListening)

        reactor.connectTCP('127.0.0.1', port.getHost().port, cf)

        return defer.gatherResults([clientProto.deferred, serverProto.deferred]) 
Example #16
Source File: test_tcp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def testNumberedInterface(self):
        f = MyServerFactory()
        # listen only on the loopback interface
        p1 = reactor.listenTCP(0, f, interface='127.0.0.1')
        return p1.stopListening() 
Example #17
Source File: test_tcp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def test_logstrClientSetup(self):
        """
        Check that the log customization of the client transport happens
        once the client is connected.
        """
        server = MyServerFactory()

        client = MyClientFactory()
        client.protocolConnectionMade = defer.Deferred()

        port = reactor.listenTCP(0, server, interface='127.0.0.1')
        self.addCleanup(port.stopListening)

        connector = reactor.connectTCP(
            port.getHost().host, port.getHost().port, client)
        self.addCleanup(connector.disconnect)

        # It should still have the default value
        self.assertEqual(connector.transport.logstr,
                          "Uninitialized")

        def cb(ign):
            self.assertEqual(connector.transport.logstr,
                              "AccumulatingProtocol,client")
        client.protocolConnectionMade.addCallback(cb)
        return client.protocolConnectionMade 
Example #18
Source File: test_tcp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def createServer(self, address, portNumber, factory):
        """
        Create a TCP server using L{IReactorTCP.listenTCP}.
        """
        return reactor.listenTCP(portNumber, factory, interface=address) 
Example #19
Source File: test_tcp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def setUp(self):
        self.f = f = MyHCFactory()
        self.p = p = reactor.listenTCP(0, f, interface="127.0.0.1")
        self.addCleanup(p.stopListening)
        d = loopUntil(lambda :p.connected)

        self.cf = protocol.ClientCreator(reactor, MyHCProtocol)

        d.addCallback(lambda _: self.cf.connectTCP(p.getHost().host,
                                                   p.getHost().port))
        d.addCallback(self._setUp)
        return d 
Example #20
Source File: test_tcp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def setUp(self):
        self.f = f = MyServerFactory()
        self.f.protocolConnectionMade = defer.Deferred()
        self.p = p = reactor.listenTCP(0, f, interface="127.0.0.1")

        # XXX we don't test server side yet since we don't do it yet
        d = protocol.ClientCreator(reactor, AccumulatingProtocol).connectTCP(
            p.getHost().host, p.getHost().port)
        d.addCallback(self._gotClient)
        return d 
Example #21
Source File: ftp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def generatePortCommand(self, portCmd):
        """
        (Private) Generates the text of a given PORT command.
        """

        # The problem is that we don't create the listening port until we need
        # it for various reasons, and so we have to muck about to figure out
        # what interface and port it's listening on, and then finally we can
        # create the text of the PORT command to send to the FTP server.

        # FIXME: This method is far too ugly.

        # FIXME: The best solution is probably to only create the data port
        #        once per FTPClient, and just recycle it for each new download.
        #        This should be ok, because we don't pipeline commands.

        # Start listening on a port
        factory = FTPDataPortFactory()
        factory.protocol = portCmd.protocol
        listener = reactor.listenTCP(0, factory)
        factory.port = listener

        # Ensure we close the listening port if something goes wrong
        def listenerFail(error, listener=listener):
            if listener.connected:
                listener.loseConnection()
            return error
        portCmd.fail = listenerFail

        # Construct crufty FTP magic numbers that represent host & port
        host = self.transport.getHost().host
        port = listener.getHost().port
        portCmd.text = 'PORT ' + encodeHostPort(host, port) 
Example #22
Source File: test_tcp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def test_listen(self):
        """
        L{IReactorTCP.listenTCP} returns an object which provides
        L{IListeningPort}.
        """
        f = MyServerFactory()
        p1 = reactor.listenTCP(0, f, interface="127.0.0.1")
        self.addCleanup(p1.stopListening)
        self.assertTrue(interfaces.IListeningPort.providedBy(p1)) 
Example #23
Source File: conch.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def onConnect():
#    if keyAgent and options['agent']:
#        cc = protocol.ClientCreator(reactor, SSHAgentForwardingLocal, conn)
#        cc.connectUNIX(os.environ['SSH_AUTH_SOCK'])
    if hasattr(conn.transport, 'sendIgnore'):
        _KeepAlive(conn)
    if options.localForwards:
        for localPort, hostport in options.localForwards:
            s = reactor.listenTCP(localPort,
                        forwarding.SSHListenForwardingFactory(conn,
                            hostport,
                            SSHListenClientForwardingChannel))
            conn.localForwards.append(s)
    if options.remoteForwards:
        for remotePort, hostport in options.remoteForwards:
            log.msg('asking for remote forwarding for %s:%s' %
                    (remotePort, hostport))
            conn.requestRemoteForwarding(remotePort, hostport)
        reactor.addSystemEventTrigger('before', 'shutdown', beforeShutdown)
    if not options['noshell'] or options['agent']:
        conn.openChannel(SSHSession())
    if options['fork']:
        if os.fork():
            os._exit(0)
        os.setsid()
        for i in range(3):
            try:
                os.close(i)
            except OSError as e:
                import errno
                if e.errno != errno.EBADF:
                    raise 
Example #24
Source File: test_cftp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def startServer(self):
        realm = FileTransferTestRealm(self.testDir)
        p = portal.Portal(realm)
        p.registerChecker(test_ssh.conchTestPublicKeyChecker())
        fac = test_ssh.ConchTestServerFactory()
        fac.portal = p
        self.server = reactor.listenTCP(0, fac, interface="127.0.0.1") 
Example #25
Source File: test_conch.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def setUp(self):
        self._createFiles()
        self.conchFactory = self._makeConchFactory()
        self.conchFactory.expectedLoseConnection = 1
        self.conchServer = reactor.listenTCP(0, self.conchFactory,
                                             interface="127.0.0.1")
        self.echoServer = reactor.listenTCP(0, EchoFactory())
        self.echoPort = self.echoServer.getHost().port
        self.echoServerV6 = reactor.listenTCP(0, EchoFactory(), interface="::1")
        self.echoPortV6 = self.echoServerV6.getHost().port 
Example #26
Source File: test_names.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def setUp(self):
        self.factory = server.DNSServerFactory([
            test_domain_com, reverse_domain, my_domain_com
        ], verbose=2)

        p = dns.DNSDatagramProtocol(self.factory)

        while 1:
            listenerTCP = reactor.listenTCP(0, self.factory, interface="127.0.0.1")
            # It's simpler to do the stop listening with addCleanup,
            # even though we might not end up using this TCP port in
            # the test (if the listenUDP below fails).  Cleaning up
            # this TCP port sooner than "cleanup time" would mean
            # adding more code to keep track of the Deferred returned
            # by stopListening.
            self.addCleanup(listenerTCP.stopListening)
            port = listenerTCP.getHost().port

            try:
                listenerUDP = reactor.listenUDP(port, p, interface="127.0.0.1")
            except error.CannotListenError:
                pass
            else:
                self.addCleanup(listenerUDP.stopListening)
                break

        self.listenerTCP = listenerTCP
        self.listenerUDP = listenerUDP
        self.resolver = client.Resolver(servers=[('127.0.0.1', port)]) 
Example #27
Source File: test_mail.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def testLocalDelivery(self):
        service = mail.mail.MailService()
        service.smtpPortal.registerChecker(cred.checkers.AllowAnonymousAccess())
        domain = mail.maildir.MaildirDirdbmDomain(service, 'domainDir')
        domain.addUser('user', 'password')
        service.addDomain('test.domain', domain)
        service.portals[''] = service.portals['test.domain']
        map(service.portals[''].registerChecker, domain.getCredentialsCheckers())

        service.setQueue(mail.relay.DomainQueuer(service))

        f = service.getSMTPFactory()

        self.smtpServer = reactor.listenTCP(0, f, interface='127.0.0.1')

        client = LineSendingProtocol([
            'HELO meson',
            'MAIL FROM: <user@hostname>',
            'RCPT TO: <user@test.domain>',
            'DATA',
            'This is the message',
            '.',
            'QUIT'
        ])

        done = Deferred()
        f = protocol.ClientFactory()
        f.protocol = lambda: client
        f.clientConnectionLost = lambda *args: done.callback(None)
        reactor.connectTCP('127.0.0.1', self.smtpServer.getHost().port, f)

        def finished(ign):
            mbox = domain.requestAvatar('user', None, pop3.IMailbox)[1]
            msg = mbox.getMessage(0).read()
            self.assertNotEqual(msg.find('This is the message'), -1)

            return self.smtpServer.stopListening()
        done.addCallback(finished)
        return done 
Example #28
Source File: test_mail.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def setUpDNS(self):
    self.auth = TestAuthority()
    factory = server.DNSServerFactory([self.auth])
    protocol = dns.DNSDatagramProtocol(factory)
    while 1:
        self.port = reactor.listenTCP(0, factory, interface='127.0.0.1')
        portNumber = self.port.getHost().port

        try:
            self.udpPort = reactor.listenUDP(portNumber, protocol, interface='127.0.0.1')
        except CannotListenError:
            self.port.stopListening()
        else:
            break
    self.resolver = client.Resolver(servers=[('127.0.0.1', portNumber)]) 
Example #29
Source File: socks.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def listenClass(self, port, klass, *args):
        serv = reactor.listenTCP(port, klass(*args))
        return defer.succeed(serv.getHost()[1:]) 
Example #30
Source File: loopback.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def loopbackTCP(server, client, port=0, noisy=True):
    """Run session between server and client protocol instances over TCP."""
    from twisted.internet import reactor
    f = policies.WrappingFactory(protocol.Factory())
    serverWrapper = _FireOnClose(f, server)
    f.noisy = noisy
    f.buildProtocol = lambda addr: serverWrapper
    serverPort = reactor.listenTCP(port, f, interface='127.0.0.1')
    clientF = LoopbackClientFactory(client)
    clientF.noisy = noisy
    reactor.connectTCP('127.0.0.1', serverPort.getHost().port, clientF)
    d = clientF.deferred
    d.addCallback(lambda x: serverWrapper.deferred)
    d.addCallback(lambda x: serverPort.stopListening())
    return d