Twisted忽略来自MUD客户端的数据?

2 投票
2 回答
710 浏览
提问于 2025-04-15 16:59

我有以下这段代码(几乎是从这里复制过来的聊天服务器示例):

import twisted.scripts.twistd
from twisted.protocols import basic
from twisted.internet import protocol, reactor
from twisted.application import service, internet

class MyChat(basic.LineReceiver):
    def connectionMade(self):
        print "Got new client!"
        self.factory.clients.append(self)

    def connectionLost(self, reason):
        print "Lost a client!"
        self.factory.clients.remove(self)

    def lineReceived(self, line):
        print "received", repr(line)
        for c in self.factory.clients:
            c.message(line)

    def message(self, message):
        self.transport.write(message + '\n')

factory = protocol.ServerFactory()
factory.protocol = MyChat
factory.clients = []

if __name__ == "__main__":
    print "Building reactor...."
    reactor.listenTCP(50000, factory)
    print "Running ractor...."
    reactor.run()
else:
    application = service.Application("chatserver")
    internet.TCPServer(50000, factory).setServiceParent(application)

这个服务器运行得很好,如果我通过Telnet连接它,我可以发送数据,服务器会在控制台上打印出来,并把数据转发给所有客户端(这正是我期待的结果)。但是,如果我通过另一个工具(一个MUD客户端)连接它,数据就收不到。

我确认客户端确实在发送数据(用Wireshark抓包,数据包确实在网络上传输),但服务器要么根本没收到,要么出于某种原因选择忽略这些数据。

我尝试过用两个MUD客户端,gmudJMC。如果这很重要,我是在Windows 7 x64上运行的。

有没有人知道这可能是什么原因呢?

谢谢,

Mike

编辑:

感谢Maiku Mori提供的提示,我尝试添加了Twisted API文档中提到的另一个方法,dataReceived。添加这个方法后,MUD客户端工作得很好,但Telnet现在每输入一个字符就会发送一次数据,而不是等用户按下Enter键。

这是新代码的一部分:

    def dataReceived(self, data):
        print "Dreceived", repr(data)
        for c in self.factory.clients:
            c.message(data)

#    def lineReceived(self, line):
#        print "received", repr(line)
#        for c in self.factory.clients:
#            c.message(line)

有没有人遇到过这种情况,如果有,怎么解决呢?理想情况下,我希望Telnet和MUD客户端都能在这个应用程序中正常工作。

再次感谢。

2 个回答

1

你确定MUD客户端在每一行后面都会发送行结束符吗?只有在发送了行结束符后,lineReceived这个函数才会被调用。

编辑:

我在这里找到了关于LineReceiver的API文档。你可以试着使用dataReceived这个方法,看看你是否真的收到了任何数据。如果我没记错的话,你可以像使用lineReceived那样使用它。

3

如果有人遇到类似的问题,我把我的发现留在这里作为最佳答案,这样大家就不用像我一样到处找了。

我通过把我的Twisted协议中的分隔符从默认的"\r\n"改成"\n"来解决了这个问题。因为我的MUD客户端发送的就是"\n"。这意味着在Telnet中,当你输入以下字符串:

Hello, World

你的应用程序会接收到:

Hello, World\r

你可能需要在服务器端对数据进行整理,以保持数据的整洁。我的最终代码如下:

import twisted.scripts.twistd
from twisted.protocols import basic
from twisted.internet import protocol, reactor
from twisted.application import service, internet

class MyChat(basic.LineReceiver):
    def __init__(self):
        self.delimiter = "\n"

    def connectionMade(self):
        print "Got new client!"
        self.factory.clients.append(self)

    def connectionLost(self, reason):
        print "Lost a client!"
        self.factory.clients.remove(self)

    def lineReceived(self, line):
        print "received", repr(line)
        for c in self.factory.clients:
            c.message(line)

    def message(self, message):
        self.transport.write(message + '\n')

factory = protocol.ServerFactory()
factory.protocol = MyChat
factory.clients = []

if __name__ == "__main__":
    print "Building reactor...."
    reactor.listenTCP(50000, factory)
    print "Running ractor...."
    reactor.run()
else:
    application = service.Application("chatserver")
    internet.TCPServer(50000, factory).setServiceParent(application)

感谢大家的帮助。

撰写回答