我已经使用扭曲的 python 编写了服务器部分。现在有 4 个客户端连接到服务器,它们向服务器发送一些数据。如果客户端 1 向服务器发送一些数据,然后服务器将该数据转发给客户端 4,类似地,当客户端 2 向服务器发送数据时,服务器将该数据转发给客户端 3。因此,我的问题是如何根据 IP 地址选择特定客户端我必须向其发送数据。在我看到的向客户端发送数据的扭曲示例中,使用了以下代码

self.transport.write("string")

如何指定必须向其发送数据的客户端的 IP 地址?

我在 tcp 服务器和客户端中的服务器也是 tcp(python 扭曲)

最佳答案



在您引用的示例中, selfProtocol 的实例或 Protocol 的子类(或提供 IProtocol 而不子类化 Protocol 的对象,这也完全没问题)。

因此 self.transport 是一个提供 ITransport 的对象(也许它提供了更具体的 ITCPTransportISSLTransport ,但这在这个问题的上下文中并不重要)。

在 Twisted 中,提供 ITransport 的对象表示两个端点之间的连接。此类连接可能是 IPv4/TCP 连接或 IPv6/TLS 连接或 AF_UNIX 连接。所有这些类型的连接的共同点是它们恰好有两个端点。数据可以从一个端点“发送”并在另一端点“接收”(反之亦然)。
self.transport.write("string") 显然不包含任何寻址信息的原因是 self.transport 已经包含该信息。

由于 self.transport 代表一个连接(并且只有一个连接:不多也不少)并且每个连接都有两个端点,这两个端点的地址必然是 self.transport 的一部分(如果不是,self.transport 不能代表那个连接)。

对象实际上比这更具体:它代表连接的一侧。它知道两个端点中的哪个在“这里”,哪个在其他地方。这意味着当您将数据写入 self.transport 时,只有一个可能的地址可以发送:self.transport 表示的连接端点,它不是“此处”。

按照惯例,该端点有一个名称。它是“同行”。 ITransport 接口(interface)定义了一个方法 getPeer ,它向您公开传输对象表示的连接的“对等”地址。 self.transport.getPeer() 返回一个表示该地址的对象。该对象的确切形状取决于您拥有的连接类型。

你问我如何根据 ip 地址选择特定的客户端。如果流经系统的数据的目的地确实由 IP 地址明确指定,那么您可以使用 getPeer 查找与所需地址匹配的连接。

但是,在设置连接后停止使用连接端点的地址更为常见。由于 NAT 的部署程度,IP 地址信息往往不可靠。在应用程序级协议(protocol)中嵌入 IP 地址并非 总是 错误,但 很难想到它是正确的示例。

幸运的是,替代方案更容易。 self.transport 已经代表某个连接。这只是一个普通的旧 Python 对象。一旦您知道哪两个客户端要相互交换数据,您只需要使用这些对象将数据发送到正确的位置。

例如,如果你有一个服务器,它只接受四个连接,一个工厂保存对它创建的 IProtocol 提供者的引用来处理每个连接(想一想:因为每个 ITransport 提供者只代表一个连接,什么?这是否意味着协议(protocol)对象的 transport 属性引用其中之一?如果两个协议(protocol)对象引用同一个传输......并且单个协议(protocol)对象的 transport 属性不能引用多个对象...... ) 作为属性 one , two , three , four 那么当这些协议(protocol)对象之一实现其 dataReceived 方法时,如下所示:

def dataReceived(self, bytes):
    message = self._parseNewData(bytes)
    if message.complete():
        self.factory.four.transport.write(message.tostring())

这一定是将数据写入与服务器建立的第四个连接。在这个例子中没有明确的寻址。只是小心使用某些 Python 对象。

谨慎使用某些 Python 对象是这个问题的总体答案。

关于python - 从扭曲的服务器向特定客户端发送数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21497195/

10-14 19:19