python扭曲的中间人实现
我需要的是一种中间人实现:我需要一个服务器,它接收来自客户端的连接(不同长度的二进制数据),并将流转发到它连接的服务器(充当客户端),然后将数据从它连接的服务器发送回客户端。python扭曲的中间人实现,python,twisted,Python,Twisted,我需要的是一种中间人实现:我需要一个服务器,它接收来自客户端的连接(不同长度的二进制数据),并将流转发到它连接的服务器(充当客户端),然后将数据从它连接的服务器发送回客户端。 它实际上在客户端和服务器之间工作,并传递它们交换的数据(这是一个流,因此它不断地从一端获取数据并发送到另一端)。 服务器是静态的,所以它总是相同的,它的地址甚至可以硬编码;但是,当客户端断开连接时,此服务器还必须断开与“真实”服务器的连接。 我一直在四处寻找,但找不到这样一个简单问题的解决方案或示例。 我所做的代码实际上是
它实际上在客户端和服务器之间工作,并传递它们交换的数据(这是一个流,因此它不断地从一端获取数据并发送到另一端)。
服务器是静态的,所以它总是相同的,它的地址甚至可以硬编码;但是,当客户端断开连接时,此服务器还必须断开与“真实”服务器的连接。
我一直在四处寻找,但找不到这样一个简单问题的解决方案或示例。
我所做的代码实际上是有效的,但我还没有找到如何将一个引用放在服务器部分(表示“这是您分配的客户机”)中,或者放在表示“这是您的服务器”的客户机中。这是我的代码:
#!/usr/bin/env python
from twisted.internet import protocol, reactor
from twisted.protocols import basic
client = None
server = None
class ServerProtocol(protocol.Protocol):
def connectionMade(self):
global server
factory = protocol.ClientFactory()
factory.protocol = ClientProtocol
server = self
reactor.connectTCP('localhost', 1324, factory)
def dataReceived(self, data):
global client
client.transport.write(data)
class ClientProtocol(protocol.Protocol):
def connectionMade(self):
global client
# Here's the instance of the client
client = self
def dataReceived(self, data):
global server
server.transport.write(data)
def main():
import sys
from twisted.python import log
log.startLogging(sys.stdout)
factory = protocol.ServerFactory()
factory.protocol = ServerProtocol
# Here's the instance of the server
server = ServerProtocol
reactor.listenTCP(2593, factory)
reactor.run()
if __name__ == '__main__':
main()
#!/usr/bin/env python
from twisted.internet import protocol, reactor
from twisted.protocols import basic
class ServerProtocol(protocol.Protocol):
def __init__(self):
self.buffer = None
self.client = None
def connectionMade(self):
factory = protocol.ClientFactory()
factory.protocol = ClientProtocol
factory.server = self
reactor.connectTCP('gameserver16.gamesnet.it', 2593, factory)
def dataReceived(self, data):
if (self.client != None):
self.client.write(data)
else:
self.buffer = data
def write(self, data):
self.transport.write(data)
print 'Server: ' + data.encode('hex')
class ClientProtocol(protocol.Protocol):
def connectionMade(self):
self.factory.server.client = self
self.write(self.factory.server.buffer)
self.factory.server.buffer = ''
def dataReceived(self, data):
self.factory.server.write(data)
def write(self, data):
self.transport.write(data)
print 'Client: ' + data.encode('hex')
def main():
import sys
from twisted.python import log
log.startLogging(sys.stdout)
factory = protocol.ServerFactory()
factory.protocol = ServerProtocol
reactor.listenTCP(2593, factory)
reactor.run()
if __name__ == '__main__':
main()
现在,关键是实例不能包含在全局对象中,应该放在两个类中:how?考虑这种方法
#!/usr/bin/env python
import sys
from twisted.internet import reactor
from twisted.internet.protocol import ServerFactory, ClientFactory, Protocol
from twisted.protocols import basic
from twisted.python import log
LISTEN_PORT = 2593
SERVER_PORT = 1234
class ServerProtocol(Protocol):
def connectionMade(self):
reactor.connectTCP('localhost', SERVER_PORT, MyClientFactory(self))
def dataReceived(self, data):
self.clientProtocol.transport.write(data)
class ClientProtocol(Protocol):
def connectionMade(self):
# Pass ServerProtocol a ref. to ClientProtocol
self.serverProtocol.clientProtocol = self;
def dataReceived(self, data):
self.serverProtocol.transport.write(data)
class MyServerFactory(ServerFactory):
protocol = ServerProtocol
def buildProtocol(self, addr):
# Create ServerProtocol
p = ServerFactory.buildProtocol(self, addr)
return p
class MyClientFactory(ClientFactory):
protocol = ClientProtocol
def __init__(self, serverProtocol_):
self.serverProtocol = serverProtocol_
def buildProtocol(self, addr):
# Create ClientProtocol
p = ClientFactory.buildProtocol(self,addr)
# Pass ClientProtocol a ref. to ServerProtocol
p.serverProtocol = self.serverProtocol
return p
def main():
log.startLogging(sys.stdout)
reactor.listenTCP(LISTEN_PORT, MyServerFactory())
reactor.run()
if __name__ == '__main__':
main()
ServerProtcol实例将自身的引用传递给MyClientFactory构造函数,然后该构造函数设置并告诉ClientProtcol它与哪个ServerProtocol实例关联
类似地,当建立ClientProtocol连接时,它使用它对ServerProtocol的引用来告诉ServerProtocol要使用什么ClientProtocol
注意:这段代码中没有错误检查,因此如果出现问题(例如,如果真正的服务器没有侦听),您可能会遇到关于NoneType的错误
重要的方面是:
reactor.connectTCP('localhost', SERVER_PORT, MyClientFactory(self))
#...
def __init__(self, serverProtocol_):
self.serverProtocol = serverProtocol_
这里,您将对ServerProtocol的引用传递给MyClientFactory构造函数。它将此引用存储在成员变量中。这样做的目的是,当客户端工厂创建ClientProtocol时,它可以将引用传递给:
# Pass ClientProtocol a ref. to ServerProtocol
p.serverProtocol = self.serverProtocol
然后,一旦从脚本连接到真正的服务器,就会发生相反的情况。ClientProtocol为ServerProtocol自身提供了一个引用:
# Pass ServerProtocol a ref. to ClientProtocol
self.serverProtocol.clientProtocol = self;
最后,两个协议都使用彼此存储的引用在接收数据时发送数据:
def dataReceived(self, data):
self.clientProtocol.transport.write(data)
#...
def dataReceived(self, data):
self.serverProtocol.transport.write(data)
我自己设法解决了这个问题,以下是我用来解决这个问题的代码,以供将来参考(或帮助任何有此问题的人)。
我认为我的解决方案和jedwards给出的解决方案都有效;现在,我只需要再研究一下他自己的,以确保我所做的是正确的:这是我第一次使用Twisted框架的应用程序,研究其他人的解决方案是学习新东西的方法!:)
#!/usr/bin/env python
from twisted.internet import protocol, reactor
from twisted.protocols import basic
client = None
server = None
class ServerProtocol(protocol.Protocol):
def connectionMade(self):
global server
factory = protocol.ClientFactory()
factory.protocol = ClientProtocol
server = self
reactor.connectTCP('localhost', 1324, factory)
def dataReceived(self, data):
global client
client.transport.write(data)
class ClientProtocol(protocol.Protocol):
def connectionMade(self):
global client
# Here's the instance of the client
client = self
def dataReceived(self, data):
global server
server.transport.write(data)
def main():
import sys
from twisted.python import log
log.startLogging(sys.stdout)
factory = protocol.ServerFactory()
factory.protocol = ServerProtocol
# Here's the instance of the server
server = ServerProtocol
reactor.listenTCP(2593, factory)
reactor.run()
if __name__ == '__main__':
main()
#!/usr/bin/env python
from twisted.internet import protocol, reactor
from twisted.protocols import basic
class ServerProtocol(protocol.Protocol):
def __init__(self):
self.buffer = None
self.client = None
def connectionMade(self):
factory = protocol.ClientFactory()
factory.protocol = ClientProtocol
factory.server = self
reactor.connectTCP('gameserver16.gamesnet.it', 2593, factory)
def dataReceived(self, data):
if (self.client != None):
self.client.write(data)
else:
self.buffer = data
def write(self, data):
self.transport.write(data)
print 'Server: ' + data.encode('hex')
class ClientProtocol(protocol.Protocol):
def connectionMade(self):
self.factory.server.client = self
self.write(self.factory.server.buffer)
self.factory.server.buffer = ''
def dataReceived(self, data):
self.factory.server.write(data)
def write(self, data):
self.transport.write(data)
print 'Client: ' + data.encode('hex')
def main():
import sys
from twisted.python import log
log.startLogging(sys.stdout)
factory = protocol.ServerFactory()
factory.protocol = ServerProtocol
reactor.listenTCP(2593, factory)
reactor.run()
if __name__ == '__main__':
main()
是的,我已经想出了这样的方法来处理它,但是我不喜欢与构造函数玩,并且添加了对客户工厂的引用。这样做很容易。然后,关于从客户机到服务器的引用,我向服务器添加了一个名为client的对象,在客户机添加自己的对象之前,该对象为“None”。然而,我的代码在我的答案中。现在,我只需在两种实现之间进行选择,您的实现还是我的实现!:)谢谢你的帮助!非常好。正是我想要的。同样的碎片。