使用 twisted python 在侦听与服务器的连接时获取用户输入

Get user input while listening for connections to server using twisted python

我目前正在尝试使用 Twisted Python 进行项目工作,我的问题具体是我尝试获取用户输入的同时还使用 listenTCP() 监听连接。我最初查找了问题,发现 stdio.StandardIO 似乎是最有效的方法,因为我已经在使用 Twisted。我还看到了在扭曲矩阵 stdin.py and also stdiodemo.py 上找到的代码示例,但是我正在努力解决如何将示例代码应用于我的特定问题,因为我需要从套接字读取并在执行 tcp 任务时收集用户输入。

我正在处理的项目要大得多,但是小示例代码说明了我正在尝试做的事情并隔离了我遇到的问题。非常感谢任何帮助解决我的问题。

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()

目前上面的代码正在返回一个未处理的错误,如下所示。这演示了我使用 stdin,然后它将数据返回到 stdout 和一个导致错误的连接的客户端:

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

您提供的回溯似乎被切断了。我尝试 运行 我机器上的代码,它显示了这个回溯:

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'

从完整的回溯中可以很容易地看出,工厂缺少 client 属性。这可以修复,例如通过将此添加到您的 ServerFactory class:

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