【问题标题】:Design question on Python network programmingPython网络编程设计题
【发布时间】:2010-09-22 19:00:38
【问题描述】:

我目前正在用 Python 编写一个项目,它有一个客户端和一个服务器部分。我的网络通信有问题,所以我需要解释一些事情......

客户端主要执行服务器告诉他的操作并将操作结果发送回服务器。我需要一种在 TCP 套接字上进行双向通信的方法。

现状

我目前在服务器端使用 Twisted 框架的 LineReceiver,在客户端使用纯 Python socket(和 ssl)(因为我无法正确实现 Twisted PushProducer)。客户端有一个Queue,里面填满了应该发送到服务器的数据;子进程不断从队列中拉取数据并将其发送到服务器(参见下面的代码)。

如果只有客户端将其结果推送给管理器,此方案运行良好。服务器不可能向客户端发送数据。更准确地说,客户端无法接收服务器发送的数据。

问题

我需要一种将命令从服务器发送到客户端的方法。

我想过在客户端循环中监听传入的数据,用于从队列中发送数据:

def run(self):
    while True:
        data = self.queue.get()
        logger.debug("Sending: %s", repr(data))
        data = cPickle.dumps(data)
        self.socket.write(data + "\r\n")
        # Here would be a good place to listen on the socket

但是这个解决方案有几个问题:

  • SSLSocket.read() 方法是一种阻塞方法
  • 如果队列中没有数据,客户端将永远不会收到任何数据

是的,我可以使用Queue.get_nowait() 代替Queue.get(),但我认为这不是一个好的解决方案。

问题

有没有什么好的方法可以通过 Twisted 实现这个要求?我真的没有太多的 Twisted 技能来找到我的方法。我什至不知道使用LineReceiver 是否是解决此类问题的好主意,因为如果它没有从客户端接收数据,它就无法发送任何数据。只有一个lineReceived 事件。

Twisted(或更一般的任何事件驱动框架)是否能够解决这个问题?我什至没有通信方面的真实事件。如果服务器决定发送数据,它应该能够发送;尽可能不需要在通信端等待任何事件。

【问题讨论】:

  • 好问题,但您接受了一个未回答的问题。 :-( 我不在乎你是否称它为服务器/客户端/其他任何东西。- P2P 不是一个扭曲的东西?

标签: python network-programming twisted event-driven-design


【解决方案1】:

“我什至不知道使用LineReceiver是否适合这种问题,因为它无法发送任何数据,如果它没有从客户端接收数据。只有一个lineReceived事件。”

您可以在任何地方使用protocol.transport.write 发送数据,而不仅仅是在lineReceived

【讨论】:

  • 是的,这就是我在LineReceiver遇到的问题。
  • 而且...我提出了一个解决方案 - 从lineReceived 以外的其他地方致电protocol.transport.write
【解决方案2】:

“我需要一种将命令从服务器发送到客户端的方法。”

不要这样做。它颠倒了“客户端”和“服务器”的通常含义。客户端扮演主动角色并从服务器发送内容或请求内容。

Twisted(或更一般的任何事件驱动框架)是否能够解决这个问题?

不应该。您正在颠倒客户端和服务器的角色。

如果服务器决定发送数据,它应该能够发送;

其实是假的。

服务器受限于等待客户端请求数据。这通常是“客户端”和“服务器”的公认含义。


“一个向客户端发送命令,一个向服务器传输结果。这个解决方案听起来更像是标准的客户端-服务器通信吗?”

没有。

如果客户端向服务器发送消息并收到服务器的响应,它将满足更常见的定义。

有时,这种事情被描述为具有“代理”,它们是——每个——一种服务器和一个“控制器”,它是所有这些服务器的单个客户端。

控制器将工作分派给代理。代理是服务器——它们监听一个端口,接受来自控制器的工作,然后工作。每个代理必须同时做两件事(通常通过select API):

  • 监控一个众所周知的套接字,它将在该套接字上接收来自唯一客户端的工作。

  • 做这项工作(在后台)。

这就是客户端-服务器通常的意思。

如果每个代理都是服务器,您会发现很多库都支持这一点。这是每个人都这样做的方式。

【讨论】:

  • 你的回答是,不要这样做,因为没有人这样做?我有一个问题,需要一个解决方案,我不认为在这里质疑这个问题是直截了当的。我考虑过连接两个 TCP 套接字,就像 FTP 一样。一种用于向客户端发送命令,另一种用于将结果传输到服务器。这个解决方案听起来更像是一个标准客户端-服务器通信吗?
  • 如果你不喜欢“client”和“server”这两个词,那么“master”和“slave”呢?还是“经理”和“工人”?许多进程连接到一个然后从它接收命令的设计没有错。您的“接受含义”受到了不必要的限制。
  • S.Lott,您可能想了解 X 协议的设计和术语。 “客户端”和“服务器”这两个词并不总是像您认为的那样。
  • 有一个明确的语义,哪一方应该做真正有助于保持软件实施健全和无问题的事情。让服务器将数据推送到客户端(而不是客户端从服务器轮询)会给您带来问题。
  • 如果您不喜欢我使用服务器和客户端的方式,请告诉我另一种解决问题的方法:经理告诉其员工完成一项工作,他们不断将结果发送给它一直工作到经理告诉他们停止或做其他事情。
猜你喜欢
  • 2010-10-09
  • 1970-01-01
  • 2012-04-27
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 2011-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多