Twisted在TCP/UDP协议之间共享变量

2 投票
3 回答
1426 浏览
提问于 2025-04-17 09:16

我有一个简单的tcp服务器示例。我想把一个计数器变量和udp服务器共享,这样每次连接时,tcp和udp的值都会增加。所以如果我先用tcp连接,它的值会变成2,然后如果我再连接udp端口,它的值就会变成3。

#!/usr/bin/env python

from twisted.internet.protocol import Factory, Protocol
from twisted.internet import reactor

class TCP(Protocol):

    def connectionMade(self):
        self.factory.counter += 1
        self.transport.write(str(self.factory.counter)+'\r\n')
        self.transport.loseConnection()

class QOTDFactory(Factory):

    def __init__(self, protocol='tcp'):
        if protocol == 'tcp':
            self.protocol = TCP
        else:
            self.protocol = UDP

        self.counter = 1

reactor.listenTCP(8007, QOTDFactory('tcp'))
#reactor.listenUDP(8007, QOTDFactory('udp'))

reactor.run()

我主要的问题是如何启动一个可以和tcp服务器一起工作的udp类,这个是我卡住的地方。我觉得我对计数器的引用是没问题的,应该可以正常工作。

3 个回答

0

你可以使用一个静态类变量来实现这个计数器:

class QOTDFactory(Factory):
    counter = 1

    def __init__(self, protocol='tcp'):
        if protocol == 'tcp':
            self.protocol = TCP
        else:
            self.protocol = UDP

        QOTDFactory.counter += 1
1

这能满足你的需求吗?

#!/usr/bin/env python

from twisted.internet.protocol import Factory, Protocol
from twisted.internet import reactor

class Counter():
  def __init__(self):
    self.count = 0

class TCP(Protocol):

    def connectionMade(self):
        self.factory.counter.count += 1
        self.transport.write(str(self.factory.counter)+'\r\n')
        self.transport.loseConnection()

class QOTDFactory(Factory):

    def __init__(self, protocol, counter):
        if protocol == 'tcp':
            self.protocol = TCP
        else:
            self.protocol = UDP

        self.counter = counter

counter = Counter()
reactor.listenTCP(8007, QOTDFactory('tcp', counter))
reactor.listenUDP(8007, QOTDFactory('udp', counter))

reactor.run()
4

在使用 reactor.listenUDP 的时候,你需要传入一个 DatagramProtocol 的实例,就像在UDP的例子中展示的那样:http://twistedmatrix.com/documents/current/core/howto/udp.html。你不能把 QOTDFactory 用在UDP上,所以不需要考虑TCP和UDP的选择逻辑。你只需要创建一个 DatagramProtocol 的子类,里面写上你想要的协议逻辑,并让它共享你TCP服务器使用的工厂的引用。

#!/usr/bin/env python

from twisted.internet.protocol import Factory, Protocol
from twisted.internet import reactor

class StreamCounter(Protocol):
    def connectionMade(self):
        self.factory.counter += 1
        self.transport.write(str(self.factory.counter)+'\r\n')
        self.transport.loseConnection()


class DatagramCounter(DatagramProtocol):
    def __init__(self, factory):
        self.factory = factory

    def datagramReceived(self, data, address):
        self.factory.counter += 1
        self.transport.write(str(self.factory.counter), address)


class QOTDFactory(Factory):
    counter = 0
    protocol = StreamCounter


factory = QOTDFactory()
reactor.listenTCP(8007, factory)
reactor.listenUDP(8007, DatagramCounter(factory))

reactor.run()

我把 TCPUDP 改名为 StreamCounterDatagramCounter,因为它们并不局限于TCP和UDP的使用(而且原来的名字也不太好理解;)。比如,你可以通过 reactor.listenSSL 使用 StreamCounter 来实现SSL连接。

撰写回答