2009-12-14 103 views
2

我有以下代碼(聊天服務器的例子的幾乎精確副本中列出here扭曲忽略來自MUD客戶端的數據?

進口twisted.scripts.twistd 從twisted.protocols導入從twisted.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。

有沒有人知道爲什麼會發生這種情況?

謝謝,

麥克

編輯:

由於由Maiku Mori提供的提示,我嘗試添加這是在Twisted API Docs,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客戶端可以使用此應用程序。

再次感謝。

回答

3

如果任何人遇到類似問題而絆倒這個問題,我會將我的發現留作公認的答案,以便人們不必以我的方式打獵。

我通過將Twisted協議中的分隔符值從「\ r \ n」(默認值)更改爲「\ n」(這是我的MUD客戶端發送的內容)來解決問題。這意味着,在遠程登錄,當你輸入的字符串:

Hello, World 

您的應用程序將獲得它:

Hello, World\r 

您可能需要做在服務器端數據衛生保持對事物的順序。我最終的代碼如下:

進口twisted.scripts.twistd 從twisted.protocols匯入twisted.internet進口協議,從twisted.application進口服務反應堆 ,互聯網

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) 

由於基本 爲所有的幫助。

+0

啊,我以爲你檢查wireshark和MUD客戶端使用暫停或別的東西作爲分隔符。那麼這是一個乾淨的解決方案:D – 2009-12-14 01:33:53

+0

基本上,您不能對客戶端是否發送\ n,\ r,\ n \ r或\ r \ n做任何假設。就我個人而言,我不會嘗試彎曲LineReceiver來處理Telnet(尤其是不是MUD流量),因爲它基本上不是基於行的協議,特別是當您考慮IAC序列,ANSI顏色等時。 – Kylotan 2009-12-14 10:15:45

+0

那麼您會建議使用什麼Twisted組件? – 2009-12-14 14:09:14

1

你確定MUD客戶端在每行之後發送行尾字符嗎? lineReceived只會在行結束字符被髮送後被調用。

編輯:

在這裏,我找到API文檔LineReceiver。你可以玩dataReceived方法來看看你是否真的獲得任何類型的數據。如果我記得你可以使用它就像lineReceived

+0

我不確定他們是否是。有沒有一種方法可以手動添加到下一個測試結束? – 2009-12-14 01:06:15

+0

那麼你可以使用Wireshark進行測試。還有其他Receiver基類可以使用。自從我閱讀Twisted API文檔以來已經有一段時間了,但我認爲還有另一種方法,一旦數據塊實時生效就會被調用,您可以使用它來查看是否有任何數據進入。但是,自從我閱讀文檔以來,這已經過去將近一年了,所以我可能是錯的。 – 2009-12-14 01:14:29

+0

你的回覆有幫助,我得到了MUD客戶端的工作,但我添加的方法打破了Telnet支持。我在我的初始文章的編輯中概述了它。 – 2009-12-14 01:17:15