【问题标题】:Twisted - send data from a server to clientTwisted - 从服务器向客户端发送数据
【发布时间】:2011-07-22 16:28:46
【问题描述】:

我是 Twisted 的新手,并且已经阅读了许多与我遇到的问题类似的相关帖子。但是,我无法推断以前的答案来解决我的简单问题。我确实参考了 Twisted 的常见问题解答部分 - 我仍然无法弄清楚。

我的问题是我有一台服务器正在监听一个端口,当我收到“START”命令时,我想与多个客户端交谈。例如,我使用了一个客户端,它为我提供幸运饼干。但是,我无法在服务器代码中与客户端交谈。你能告诉我哪里出错了吗?代码如下:

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

class FakeTelnet(Protocol):
    def connectionMade(self):
        print 'local connection made'
        self.otherFact = protocol.ClientFactory()
        self.otherFact.protocol = EchoClient
        self.factory.clients.append(self.otherFact.protocol)
        reactor.connectTCP('psrfb6',10999, self.otherFact)

    def dataReceived(self, data):

        if 'START' in data:
            # send a command to cookie server.
            for client in self.factory.clients:
                client.transport.write('START\r\n')

    def connectionLost(self):
        print 'connection lost'

class EchoClient(Protocol):
    """Once connected, send a message, then print the result."""

    def connectionMade(self):
        print "Connection to cookie server"

    def dataReceived(self, data):
        "As soon as any data is received, write it back."
        print "Fortune Server said:", data

    def connectionLost(self):
        print "connection lost"

    def send_stuff(data):
        self.transport.write(data);

class MyFactory(Factory):
    protocol = FakeTelnet
    def __init__(self, EchoClient):
        self.clients = []
        self.otherCli = EchoClient

reactor.listenTCP(5823, MyFactory(EchoClient))
reactor.run()

【问题讨论】:

  • 一个简短的更新:我检查了这个常见问题解答:twistedmatrix.com/trac/wiki/… - 但我仍然无法理解它。我想要的是使用在 FakeTelnet 中建立的客户端连接在 dataReceived 中可用。任何帮助将不胜感激。谢谢。

标签: python twisted


【解决方案1】:
class FakeTelnet(Protocol):
    def connectionMade(self):
        print 'local connection made'
        self.otherFact = protocol.ClientFactory()
        self.otherFact.protocol = EchoClient

在这里,您将self.otherFact.protocol 设置为EchoClient

        self.factory.clients.append(self.otherFact.protocol)

在这里,您将EchoClient 添加到self.factory.clients 列表中。这只会导致self.factory.clients 一遍又一遍地成为一个充满EchoClient 的列表。

def dataReceived(self, data):
    if 'START' in data:
        # send a command to cookie server.
        for client in self.factory.clients:
            client.transport.write('START\r\n')

在这里您尝试写信给EchoClient.transport,通常是None,因为它只是连接到传输的协议类的实例,而不是类本身。

尝试将连接的实例添加到self.factory.clients。我认为您正在设法创建此类实例,因为您在FakeTelnet.connectionMade 中也有这一行:

    reactor.connectTCP('psrfb6',10999, self.otherFact)

但是,您没有做任何让您将连接的协议放入self.factory.clients 列表的事情。也许你可以这样定义self.otherFact

class OtherFactory(ClientFactory):
    protocol = EchoClient

    def __init__(self, originalFactory):
        self.originalFactory = originalFactory

    def buildProtocol(self, addr):
        proto = ClientFactory.buildProtocol(self, addr)
        self.originalFactory.clients.append(proto)
        return proto

您还希望在某个时候从clients 列表中删除 项。或许在协议的connectionLost回调中:

class EchoClient(Protocol):
    ...
    def connectionLost(self, reason):
        self.factory.originalFactory.clients.remove(self)

最后,如果您正在处理面向行的数据,您可能希望使用twisted.protocols.basic.LineOnlyReceiver 作为FakeTelnet 的基类并将您的逻辑放在其lineReceived 回调中。 dataReceived 回调不保证数据边界,因此您可能永远不会看到包含"START" 的单个字符串。例如,您可能会收到两个对dataReceived 的调用,一个是"ST",另一个是"ART"

【讨论】:

    猜你喜欢
    • 2013-05-01
    • 2014-09-07
    • 2015-02-10
    • 1970-01-01
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    • 2016-07-21
    • 1970-01-01
    相关资源
    最近更新 更多