【发布时间】:2011-03-13 05:02:12
【问题描述】:
我有以下情况:
SomeServer(S) <-> (C)MyApp(S) <-> (C)User
(S) represents a server socket
(C) represents a client socket
基本上,MyApp 会启动与 SomeServer (SomeServer(S) (C)MyApp) 的通信,并且一旦某些身份验证例程成功的 MyApp(S) 开始等待 (C)User 连接。 User 连接后,MyApp 会将数据从 SomeServer 中继到 User。这发生在两个方向。
我的 SomeServer(S) (C)MyApp 运行良好,但我无法获得 MyApp(S) (C)User强>工作。我的 User 连接到 MyApp(S),但无法中继数据!
好的,我希望这很清楚 ;) 现在让我展示我的 MyApp 代码。顺便说一句,SomeServer 和 User 的实现与解决我的问题不相关,因为两者都不能修改。
我已对我的代码进行了注释,指出我遇到问题的地方。哦,我还应该提到,如果有必要,我可以为其他代码废弃整个“服务器部分”。这是一个 POC,所以我的主要关注点是让功能正常工作,而不是编写高效的代码。谢谢你的时间。
''' MyApp.py module '''
import asyncore, socket
import SSL
# Client Section
# Connects to SomeServer
class MyAppClient(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((host, port))
connectionPhase = 1
def handle_read(self):
print "connectionPhase =", self.connectionPhase
# The following IF statements may not make sense
# as I have removed code irrelevant to this question
if self.connectionPhase < 3: # authentication phase
data = self.recv(1024)
print 'Received:', data
# Client/Server authentication is handled here
# Everything from this point on happens over
# an encrypted socket using SSL
# Start the RelayServer listening on localhost 8080
# self.socket is encrypted and is the socket communicating
# with SomeServer
rs = RelayServer(('localhost', 8080), self.socket)
print 'RelayServer started'
# connectionPhase = 3 when this IF loop is done
elif self.connectionPhase == 3: # receiving data for User
data = self.recv(1024)
print 'Received data - forward to User:', data
# Forward this data to User
# Don't understand why data is being read here
# when the RelayServer was instantiated above
# Server Section
# Connects to User
class RelayConnection(asyncore.dispatcher):
def __init__(self, client, sock):
asyncore.dispatcher.__init__(self)
self.client = client
print "connecting to %s..." % str(sock)
def handle_connect(self):
print "connected."
# Allow reading once the connection
# on the other side is open.
self.client.is_readable = True
# For some reason this never runs, i.e. data from SomeServer
# isn't read here, but instead in MyAppClient.handle_read()
# don't know how to make it arrive here instead as it should
# be relayed to User
def handle_read(self):
self.client.send(self.recv(1024))
class RelayClient(asyncore.dispatcher):
def __init__(self, server, client, sock):
asyncore.dispatcher.__init__(self, client)
self.is_readable = False
self.server = server
self.relay = RelayConnection(self, sock)
def handle_read(self):
self.relay.send(self.recv(1024))
def handle_close(self):
print "Closing relay..."
# If the client disconnects, close the
# relay connection as well.
self.relay.close()
self.close()
def readable(self):
return self.is_readable
class RelayServer(asyncore.dispatcher):
def __init__(self, bind_address, MyAppClient_sock):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.bind(bind_address)
self.MyAppClient_sock = MyAppClient_sock
print self.MyAppClient_sock
self.listen(1)
def handle_accept(self):
conn, addr = self.accept()
RelayClient(self, conn, self.MyAppClient_sock)
if __name__ == "__main__":
# Connect to host
# First connection stage
connectionPhase = 1
c = MyAppClient('host', port) # SomeServer's host and port
asyncore.loop()
编辑:
@samplebias 我用您的代码(未显示)替换了我的完整模块,并且我重新添加了身份验证等所需的所有点点滴滴。
此时我得到了与上面我自己的代码相同的结果。我的意思是 MyApp(或代码中的 Server)连接到 SomeServer 并来回传递数据。到目前为止一切都很好。当用户(或客户端应用程序)连接到 localhost 8080 时,运行此代码:
if not self.listener:
self.listener = Listener(self.listener_addr, self)
但是,这没有运行
# if user is attached, send data
elif self.user:
print 'self.user'
self.user.send(data)
因此,服务器没有将数据中继给用户。我在整个 User 类中添加了打印语句以查看运行的内容,而 init 是唯一的。 handle_read() 从不运行。
这是为什么?
【问题讨论】:
-
您应该查看PEP8,如果您遵循它,您的代码不会破坏 SO 的代码标记;-)
标签: python sockets asynchronous asyncore