我已经使用扭曲的 python 编写了服务器部分。现在有 4 个客户端连接到服务器,服务器将一些数据发送到服务器。如果客户端 1 向服务器发送一些数据,则服务器将该数据转发给客户端 4,同样,当客户端 2 向服务器发送数据时,服务器将该数据转发给客户端 3。因此我的问题是如何根据 IP 地址选择特定客户端我必须向其发送数据。在我看到的向客户端发送数据的扭曲示例中,使用了以下代码
self.transport.write("string")
如何指定我必须向其发送数据的客户端的 IP 地址?
我在 tcp 服务器和客户端中的服务器也是 tcp(python 扭曲)
最佳答案
self.transport.write("string")
在您引用的示例中,
self
是 Protocol
的一个实例或 Protocol
的子类(或提供 IProtocol
而没有子类 Protocol
的对象,这也完全没问题)。self.transport
因此是一个提供 ITransport
的对象(也许它提供了更具体的 ITCPTransport
或 ISSLTransport
但这在这个问题的上下文中并不重要)。在 Twisted 中,提供
ITransport
的对象表示两个端点之间的连接。这样的连接可能是 IPv4/TCP 连接或 IPv6/TLS 连接或 AF_UNIX 连接。所有这些类型的连接的共同点是它们恰好有两个端点。数据可以从一个端点“发送”并在另一个端点“接收”(反之亦然)。原因
self.transport.write("string")
显然不包含任何寻址信息是 self.transport
已经包含该信息。由于
self.transport
表示一个连接(并且只有一个连接:不多也不少)并且每个连接都有两个端点,这两个端点的地址必然是self.transport
的一部分(如果不是,self.transport
不能代表这种联系)。这个对象实际上比这更具体一点:它代表连接的一侧。它知道两个端点中的哪一个在“这里”,哪一个在其他地方。这意味着当您将数据写入
self.transport
它只能发送到一个可能的地址:self.transport
表示的连接的端点这不是“这里”。按照惯例,该端点有一个名称。它是“同行”。接口(interface)
ITransport
定义一个方法,getPeer
,它向您公开传输对象所代表的连接的“对等”地址。 self.transport.getPeer()
返回一个表示该地址的对象。该对象的确切形状取决于您拥有的连接类型。您问我如何根据 IP 地址选择特定客户端。如果确实是流经您系统的数据的目的地由 IP 地址明确指定,那么您可以使用
getPeer
查找与所需地址匹配的连接。但是,在设置连接后停止使用连接的端点地址更为常见。由于 NAT 的部署程度,IP 地址信息往往不可靠。不是总是 在您的应用程序级协议(protocol)中嵌入 IP 地址是错误的,但它 是 很难想出正确的例子。
幸运的是,替代方案更容易。
self.transport
已经代表了某种联系。这只是一个普通的旧 Python 对象。一旦您知道哪两个客户端要相互交换数据,您只需使用对象将数据发送到正确的位置。例如,如果您的服务器正好接受四个连接,并且工厂保存了对
IProtocol
的引用。它为处理每个连接而创建的提供程序(请考虑一下:由于每个 ITransport
提供程序仅代表一个连接,那么对于具有引用其中一个的 transport
属性的协议(protocol)对象来说,这意味着什么?如果两个协议(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/