【问题标题】:How can I close a port and also kill all active connections ASAP?如何关闭端口并尽快终止所有活动连接?
【发布时间】:2015-02-08 19:40:55
【问题描述】:

我有一个服务器正在运行,它产生新的 TCP 端口来实现端口转发代理。我需要能够尽快移除端口并断开所有客户端。

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

后来

port.loseConnection()

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

【问题讨论】:

  • 如果在端口上调用loseConnection 将其关闭,这是实现的意外。您正在寻找的方法是stopListening。这并不能回答您的问题,但它确实指出了您拥有的其他代码可能存在的问题。

标签: python proxy twisted


【解决方案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)

【讨论】:

    猜你喜欢
    • 2015-01-03
    • 2020-08-16
    • 2019-05-29
    • 2018-11-26
    • 2011-01-31
    • 1970-01-01
    • 2015-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多