我已经使用扭曲的 python 编写了服务器部分。现在有 4 个客户端连接到服务器,它们向服务器发送一些数据。如果客户端 1 向服务器发送一些数据,然后服务器将该数据转发给客户端 4,类似地,当客户端 2 向服务器发送数据时,服务器将该数据转发给客户端 3。因此,我的问题是如何根据 IP 地址选择特定客户端我必须向其发送数据。在我看到的向客户端发送数据的扭曲示例中,使用了以下代码
self.transport.write("string")
如何指定必须向其发送数据的客户端的 IP 地址?
我在 tcp 服务器和客户端中的服务器也是 tcp(python 扭曲)
最佳答案
在您引用的示例中, 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
表示的连接端点,它不是“此处”。
按照惯例,该端点有一个名称。它是“同行”。 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/