2016-05-30 4 views
1

Ich versuche gerade an einem Projekt mit Twisted Python zu arbeiten, mein Problem ist speziell mein Versuch, Benutzereingaben zu erhalten, während ich auch auf Verbindungen mit lifeTCP() lausche. Ich habe das Problem ursprünglich nachgeschlagen und festgestellt, dass stdio.StandardIO die effizienteste Methode ist, dies zu tun, da ich Twisted bereits verwende. Ich habe auch die Codebeispiele auf Twisted Matrix, stdin.py und auch stdiodemo.py gefunden, aber ich habe Probleme damit, Beispielcode auf mein spezifisches Problem anzuwenden, da ich aus dem Socket lesen und auch Benutzereingaben erfassen muss, während ich tcp-Aufgaben ausführe.Erhalten Sie Benutzereingaben, während Sie mit twisted python auf Verbindungen zum Server warten

Das Projekt, an dem ich arbeite, ist viel größer, aber der kleine Beispielcode zeigt, was ich versuche zu tun und isoliert das Problem, das ich habe. Jede Hilfe bei der Lösung meines Problems wird sehr geschätzt.

Server.py

from twisted.internet.protocol import Factory 
from twisted.protocols import basic 
from twisted.internet import reactor, protocol, stdio 
from Tkinter import * 
import os, sys 

class ServerProtocol(protocol.Protocol): 
    def __init__(self, factory): 
     self.factory = factory 
     stdio.StandardIO(self) 

    def connectionMade(self): 
     self.factory.numConnections += 1 
     self.factory.clients.append(self) 

    def dataReceived(self, data): 
     try: 
      print 'receiving data' 
      print data 
     except Exception, e: 
      print e 

    def connectionLost(self, reason): 
     self.factory.numConnections -= 1 
     self.factory.clients.remove(self) 

class ServerFactory(Factory): 
    numConnections = 0 
    def buildProtocol(self, addr): 
     return ServerProtocol(self) 

class StdioCommandLine(basic.LineReceiver): 
    from os import linesep as delimiter 
    def connectionMade(self): 
     self.transport.write('>>> ') 
    def lineReceived(self, line): 
     self.sendLine('Echo: ' + line) 
     self.transport.write('>>> ') 

reactor.listenTCP(9001, ServerFactory()) 
stdio.StandardIO(StdioCommandLine()) 
reactor.run() 

Client.py

from twisted.internet import reactor, protocol 
import os, time, sys 
import argparse 

class MessageClientProtocol(protocol.Protocol): 

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

    def connectionMade(self): 
     self.sendMessage() 

    def sendMessage(self): 
     print 'sending message' 
     try: 
      self.transport.write('hello world') 
     except e as Exception: 
      print e 

    def dataReceived(self, data): 
     print 'received: ', data 
     self.sendMessage() 

class MessageClientFactory(protocol.ClientFactory): 

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

    def buildProtocol(self, addr): 
     return MessageClientProtocol(self) 

    def clientConnectionFailed(self, connector, reason): 
     print 'Connection Failed: ', reason.getErrorMessage() 
     reactor.stop() 

    def clientConnectionLost(self, connector, reason): 
     print 'Connection Lost: ', reason.getErrorMessage() 

reactor.connectTCP('192.168.1.70', 9001, MessageClientFactory('hello world - client')) 
reactor.run() 

Im Moment der obige Code eine unhanded Fehler zurückgibt, wie folgt. Dies zeigt mir mit stdin, dann Rückkehr es die Daten an stdout und einem Client die Verbindung herstellt den Fehler verursacht:

python Server.py

>>> hello

Echo: hello

>>> Unhandled Error Traceback (most recent call last):

File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/python/log.py", line 84, in callWithContext

return context.call({ILogContext: newCtx}, func, *args, **kw)

File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/python/context.py", line 118, in callWithContext return self.currentContext().callWithContext(ctx, func, *args, **kw)

File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/python/context.py", line 81, in callWithContext

return func(*args,**kw)

File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/internet/selectreactor.py", line 149, in _doReadOrWrite

why = getattr(selectable, method)()

--- exception caught here ---

File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/internet/tcp.py", line 1067, in doRead
protocol = s

+0

Das Ende Ihrer Traceback scheint abgeschnitten zu sein. –

+0

Sorry 'Protokoll = s' ist die letzte Zeile, aber das ist der Gesamtfehler, der angezeigt wird. Nur um hinzuzufügen, nachdem der Client eine Verbindung zum Server herstellt, wird der obige Fehler angezeigt und ich kann weiterhin Benutzereingaben bereitstellen. Bei weiteren Clientverbindungen wird ebenfalls derselbe Fehler angezeigt. – KernelMode

+0

Das ist seltsam. Betrachtet man den Code in tcp.py, Zeile 1067, sollte die Zeile "protocol = self.factory.buildProtocol (self._buildAddr (addr))" lauten. –

Antwort

0

Die Zurückverfolgungs Sie scheint vorgesehen abgeschnitten werden. Ich habe versucht, den Code auf meinem Rechner laufen zu lassen und es zeigt diese Zurückverfolgungs:

Traceback (most recent call last): 
    File "/usr/lib/python2.7/site-packages/twisted/python/log.py", line 84, in callWithContext 
    return context.call({ILogContext: newCtx}, func, *args, **kw) 
    File "/usr/lib/python2.7/site-packages/twisted/python/context.py", line 118, in callWithContext 
    return self.currentContext().callWithContext(ctx, func, *args, **kw) 
    File "/usr/lib/python2.7/site-packages/twisted/python/context.py", line 81, in callWithContext 
    return func(*args,**kw) 
    File "/usr/lib/python2.7/site-packages/twisted/internet/posixbase.py", line 597, in _doReadOrWrite 
    why = selectable.doRead() 
--- <exception caught here> --- 
    File "/usr/lib/python2.7/site-packages/twisted/internet/tcp.py", line 1067, in doRead 
    protocol = self.factory.buildProtocol(self._buildAddr(addr)) 
    File "Server.py", line 30, in buildProtocol 
    return ServerProtocol(self) 
    File "Server.py", line 10, in __init__ 
    stdio.StandardIO(self) 
    File "/usr/lib/python2.7/site-packages/twisted/internet/_posixstdio.py", line 42, in __init__ 
    self.protocol.makeConnection(self) 
    File "/usr/lib/python2.7/site-packages/twisted/internet/protocol.py", line 490, in makeConnection 
    self.connectionMade() 
    File "Server.py", line 14, in connectionMade 
    self.factory.clients.append(self) 
exceptions.AttributeError: ServerFactory instance has no attribute 'clients' 

Wie leicht mit dem vollständigen Zurückverfolgungs zu sehen, die Fabrik fehlt das client Attribut. Dies kann z.B. indem Sie das zu Ihrer ServerFactory Klasse hinzufügen:

def __init__(self): 
    self.clients = [] 
+0

Während das Obige das Problem nicht vollständig korrigierte, brachte es mich dazu, über die unterdrückte Ausgabe nachzudenken. Ich bootete eine VM mit Ubuntu an und lief den selben Code, es erschienen volle Fehlermeldungen und ich habe nun die obige Antwort implementiert und den Code neu geschrieben, da ich jetzt das ganze Bild habe. Ich finde es komisch, dass ich auf OSX 'el capitan' 10.11.4 mit der neuesten Version von twisted nicht die gleichen Fehler bekam, aber ich danke dir, dass du mir geholfen hast, eine Schlussfolgerung zu meinem Problem zu finden. – KernelMode

Verwandte Themen