扭曲的服务器-客户端数据共享 [英] Twisted server-client data sharing
问题描述
我稍微修改了这个站点上的一个服务器-客户端 Twisted 程序,它提供了一个可以充当服务器和客户端的程序(如何编写一个同时也是客户端的扭曲服务器?).我能够将服务器客户端连接到一侧的外部客户端和另一侧的外部服务器.我想通过服务器-客户端程序将数据从外部客户端传输到外部服务器.我遇到的问题是将 ServerProtocol 类(在服务器-客户端程序中)中接收到的行放入 ClientProtocol 类(在服务器-客户端程序中).我已经尝试了多种方法来做到这一点,包括尝试使用工厂参考,正如您从 def init 看到的那样,但我无法让它工作.(目前我只是向外部服务器和客户端来回发送文字)这是服务器 - 客户端代码:
来自twisted.internet 导入协议,反应器从twisted.protocols 导入基本类 ServerProtocol(basic.LineReceiver):def lineReceived(self, line):打印服务器-客户端接收到的行",行self.sendLine(从服务器客户端回到你")工厂 = 协议.ClientFactory()factory.protocol = ClientProtocolreactor.connectTCP('localhost', 1234, factory)类 ClientProtocol(basic.LineReceiver):def __init__(self, factory):self.factory = 工厂def connectionMade(self):self.sendLine(来自服务器客户端的你好!")#self.transport.loseConnection()def lineReceived(self, line):打印在 server-client1.py 上收到的行",行#self.transport.loseConnection()定义主():导入系统从twisted.python 导入日志log.startLogging(sys.stdout)工厂 = 协议.ServerFactory()factory.protocol = 服务器协议reactor.listenTCP(4321,工厂)反应器运行()如果 __name__ == '__main__':主要的()
我应该提到,我能够分别在端口 4321 和 1234 上连接到带有外部服务器和外部客户端的服务器-客户端程序,它们只是回显.此外,我还没有展示我多次尝试使用 self.factory 参考.任何意见或建议将不胜感激.
这个问题与 Twisted 常见问题解答中的一个流行问题非常相似:
与您关于一个传入客户端连接和一个传出客户端连接的问题相比,FAQ 项目讨论的是到一台服务器的多个客户端连接并没有任何显着差异.不同连接之间共享数据的方式是一样的.
该常见问题解答的基本要点是,基本上您想做的任何事情都涉及某种方法调用,并且 Twisted 中的方法调用与任何其他 Python 程序中的方法调用相同.您所需要的只是引用正确的对象来调用该方法.因此,例如,调整您的代码:
来自twisted.internet 导入协议,反应器从twisted.protocols 导入基本类 ServerProtocol(basic.LineReceiver):def lineReceived(self, line):self._received = 行工厂 = 协议.ClientFactory()factory.protocol = ClientProtocolfactory.originator = 自己reactor.connectTCP('localhost', 1234, factory)def forwardLine(自己,收件人):收件人.sendLine(self._received)类 ClientProtocol(basic.LineReceiver):def connectionMade(self):self.factory.originator.forwardLine(self)self.transport.loseConnection()定义主():导入系统从twisted.python 导入日志log.startLogging(sys.stdout)工厂 = 协议.ServerFactory()factory.protocol = 服务器协议reactor.listenTCP(4321,工厂)反应器运行()如果 __name__ == '__main__':主要的()
注意方法:
- 我去掉了
ClientProtocol
上的__init__
方法.ClientFactory
不带参数调用它的协议.需要参数的__init__
将导致引发TypeError
.此外,ClientFactory
已经将自己设置为它创建的协议的工厂属性. - 我通过将
ServerProtocol
实例设置为originator
属性,为ClientProtocol
提供了对ServerProtocol
实例的引用客户工厂.由于ClientProtocol
实例引用了ClientFactory
实例,这意味着它引用了ServerProtocol
实例. - 我添加了
forwardLine
方法,一旦ClientProtocol
连接建立.请注意,由于上一点,ClientProtocol
调用此方法没有问题.
I slightly modified a server-client Twisted program on this site, which provided a program that could act as a server and a client (How to write a twisted server that is also a client?). I am able to connect the server-client to an external client on one side and an external server on the other. I want to transfer data from the external client to the external server via the server-client program. The problem I am having is getting the line received in the ServerProtocol class (in the server-client program) into the ClientProtocol class (in the server-client program). I have tried a number of ways of doing this, including trying to use the factory reference, as you can see from the def init but I cannot get it to work. (at the moment I am just sending literals back and forth to the external server and client) Here is the server-client code:
from twisted.internet import protocol, reactor
from twisted.protocols import basic
class ServerProtocol(basic.LineReceiver):
def lineReceived(self, line):
print "line recveived on server-client",line
self.sendLine("Back at you from server-client")
factory = protocol.ClientFactory()
factory.protocol = ClientProtocol
reactor.connectTCP('localhost', 1234, factory)
class ClientProtocol(basic.LineReceiver):
def __init__(self, factory):
self.factory = factory
def connectionMade(self):
self.sendLine("Hello from server-client!")
#self.transport.loseConnection()
def lineReceived(self, line):
print "line recveived on server-client1.py",line
#self.transport.loseConnection()
def main():
import sys
from twisted.python import log
log.startLogging(sys.stdout)
factory = protocol.ServerFactory()
factory.protocol = ServerProtocol
reactor.listenTCP(4321, factory)
reactor.run()
if __name__ == '__main__':
main()
I should mention that I am able to connect to the server-client program with the external server and external client on ports 4321 and 1234 respectively and they just echo back. Also, I have not shown my many attempts to use the self.factory reference. Any advice or suggestions will be much appreciated.
This question is very similar to a popular one from the Twisted FAQ:
How do I make input on one connection result in output on another?
It doesn't make any significant difference that the FAQ item is talking about many client connections to one server, as opposed to your question about one incoming client connection and one outgoing client connection. The way you share data between different connections is the same.
The essential take-away from that FAQ item is that basically anything you want to do involves a method call of some sort, and method calls in Twisted are the same as method calls in any other Python program. All you need is to have a reference to the right object to call the method on. So, for example, adapting your code:
from twisted.internet import protocol, reactor
from twisted.protocols import basic
class ServerProtocol(basic.LineReceiver):
def lineReceived(self, line):
self._received = line
factory = protocol.ClientFactory()
factory.protocol = ClientProtocol
factory.originator = self
reactor.connectTCP('localhost', 1234, factory)
def forwardLine(self, recipient):
recipient.sendLine(self._received)
class ClientProtocol(basic.LineReceiver):
def connectionMade(self):
self.factory.originator.forwardLine(self)
self.transport.loseConnection()
def main():
import sys
from twisted.python import log
log.startLogging(sys.stdout)
factory = protocol.ServerFactory()
factory.protocol = ServerProtocol
reactor.listenTCP(4321, factory)
reactor.run()
if __name__ == '__main__':
main()
Notice how:
- I got rid of the
__init__
method onClientProtocol
.ClientFactory
calls its protocol with no arguments. An__init__
that requires an argument will result in aTypeError
being raised. Additionally,ClientFactory
already sets itself as the factory attribute of protocols it creates. - I gave
ClientProtocol
a reference to theServerProtocol
instance by setting theServerProtocol
instance as theoriginator
attribute on the client factory. Since theClientProtocol
instance has a reference to theClientFactory
instance, that means it has a reference to theServerProtocol
instance. - I added the
forwardLine
method whichClientProtocol
can use to directServerProtocol
to do whatever your application logic is, once theClientProtocol
connection is established. Notice that because of the previous point,ClientProtocol
has no problem calling this method.
这篇关于扭曲的服务器-客户端数据共享的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!