Twisted忽略来自MUD客户端的数据?
我有以下这段代码(几乎是从这里复制过来的聊天服务器示例):
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客户端,gmud和JMC。如果这很重要,我是在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 个回答
你确定MUD客户端在每一行后面都会发送行结束符吗?只有在发送了行结束符后,lineReceived这个函数才会被调用。
编辑:
我在这里找到了关于LineReceiver的API文档。你可以试着使用dataReceived这个方法,看看你是否真的收到了任何数据。如果我没记错的话,你可以像使用lineReceived那样使用它。
如果有人遇到类似的问题,我把我的发现留在这里作为最佳答案,这样大家就不用像我一样到处找了。
我通过把我的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)
感谢大家的帮助。