如何关闭端口并尽快终止所有活动连接?

时间:2015-02-08 19:40:56

标签: python proxy twisted

我运行的服务器产生了实现端口代理的新TCP端口。我需要能够删除端口并尽快断开所有客户端。

factory = ProxyFactory(host, port)
port = reactor.listenTCP(0, factory)

然后再

port.loseConnection()

这将关闭端口,但活动连接未关闭!如何关闭端口并终止所有连接?

1 个答案:

答案 0 :(得分:1)

我使用以下代码解决了这个问题。 RPC 是添加新代理的管理服务器, ProxyClient 会覆盖 twisted.protocols.portforward.ProxyClient

基本上,当我想要杀死他们的传输时,我必须自己跟踪客户并拨打 abortConnection

from twisted.internet import protocol, reactor, error
from twisted.web import xmlrpc, server
from twisted.python import log, failure
import socket

class RPC(xmlrpc.XMLRPC):
    proxies = {} # (host, port): tcp.Port()
    clients = [] # list of active client transports

    def __get(self, host, port):
        if (host, port) in self.proxies.keys():
            return self.proxies.get((host, port))
        return self.__new(host, port)

    def __new(self, host, port):
        factory = ProxyFactory(host, port)
        tcp_port = reactor.listenTCP(0, factory)
        self.proxies[(host, port)] = tcp_port
        return tcp_port

    def xmlrpc_get(self, host, port):
        log.msg('get {}'.format(host, port))
        port = self.__get(host, port)
        return port.getHost().port

    def xmlrpc_kill(self, host, port):
        log.msg('kill {}'.format(host, port))
        tcp_port = self.proxies.pop((host, port), None)
        if not tcp_port:
            return False
        tcp_port.loseConnection() # don't listen anymore
        try:
            ip = socket.gethostbyname(host)
        except:
            return False
        for client in list(self.clients):
            # kill connections now because we're anxious
            peer = client.getPeer()
            if (ip, port) == (peer.host, peer.port):
                log.msg('abort {}'.format(client))
                client.abortConnection()
                self.clients.remove(client)
        return True


class ProxyClient(Proxy):
    def connectionMade(self):
        RPC.clients.append(self.transport)
        self.peer.setPeer(self)

        # Wire this and the peer transport together to enable
        # flow control (this stops connections from filling
        # this proxy memory when one side produces data at a
        # higher rate than the other can consume).
        self.transport.registerProducer(self.peer.transport, True)
        self.peer.transport.registerProducer(self.transport, True)

        # We're connected, everybody can read to their hearts content.
        self.peer.transport.resumeProducing()

    def connectionLost(self, reason):
        if self.transport in RPC.clients:
            RPC.clients.remove(self.transport)