简体   繁体   English

从扭曲的服务器向特定客户端发送数据

[英]sending data to particular client from twisted server

I have written server part using twisted python. 我使用twisted python编写了服务器部分。 Now 4 clients are connected to server which send some data to server. 现在有4个客户端连接到服务器,后者向服务器发送一些数据。 If client 1 sends some data to server then server forwards that data to client 4 and similarly when client 2 sends data to server then server forwards that data to client 3. Thus my problem is that how can I choose particular client on basis of ip address to which I have to send data. 如果客户端1向服务器发送一些数据,则服务器将该数据转发给客户端4,类似地,当客户端2向服务器发送数据时,服务器将该数据转发给客户端3.因此我的问题是如何根据IP地址选择特定客户端我必须向其发送数据。 In the twisted examples that I have seen to send data to client following code is used 在我看到的使用代码后向客户端发送数据的扭曲示例中

self.transport.write("string")

How can I specify ip address of client to which I have to send data? 如何指定我必须向其发送数据的客户端的IP地址?

My server in tcp server and clients are also tcp(python twisted) 我在tcp服务器和客户端的服务器也是tcp(python twisted)

self.transport.write("string") self.transport.write( “字符串”)

In the examples you refer to, self is an instance of Protocol or a subclass of Protocol (or an object that provides IProtocol without subclassing Protocol , which is also completely fine). 在你指的是实施例中, self是的实例Protocol或子类Protocol (或提供对象IProtocol没有子类Protocol ,这也完全细)。

self.transport is therefore an object that provides ITransport (perhaps it provides the more specific ITCPTransport or ISSLTransport but that's not important in the context of this question). 因此, self.transport是一个提供 ITransport的对象(可能它提供了更具体的ITCPTransportISSLTransport但在这个问题的上下文中并不重要)。

In Twisted, an object that provides ITransport represents a connection between two endpoints. 在Twisted中, 提供 ITransport的对象表示两个端点之间的连接。 Such a connection might be an IPv4/TCP connection or an IPv6/TLS connection or an AF_UNIX connection. 此类连接可能是IPv4 / TCP连接或IPv6 / TLS连接或AF_UNIX连接。 What all of these kinds of connections have in common is that they have exactly two endpoints. 所有这些类型的连接的共同点是它们只有两个端点。 Data can be "sent" from one endpoint and "received" at the other endpoint (and vice versa). 数据可以从一个端点“发送”并在另一个端点“接收”(反之亦然)。

The reason self.transport.write("string") doesn't obviously include any addressing information is that self.transport already includes that information. self.transport.write("string")显然不包含任何寻址信息的原因是self.transport已经包含该信息。

Since self.transport represents a connection (and only one connection: no more, no less) and every connection has two endpoints, the addresses of those two endpoints are necessarily part of self.transport (were they not, self.transport could not represent that connection). 由于self.transport表示一个连接(并且只有一个连接:不多也不少),并且每个连接都有两个端点,这两个端点的地址必然是self.transport一部分(如果不是, self.transport就无法表示那个连接)。

And the object is actually slightly more specific than this: it represents one side of the connection. 并且该对象实际上比这更具体:它代表连接的一侧 It knows which of the two endpoints is "here" and which is somewhere else. 它知道两个端点中的哪一个“在这里”,哪个在其他地方。 This means that when you write data to self.transport there is only one possible address to which it can be sent: the endpoint of the connection represented by self.transport which is not "here". 这意味着当您向self.transport写入数据时,只有一个可以发送的地址: self.transport表示的连接的端点,它不是“here”。

By convention, that endpoint has a name. 按照惯例,该端点具有名称。 It is the "peer". 它是“同行”。 The interface ITransport defines a method, getPeer , which exposes to you the "peer" address of the connection the transport object represents. 接口ITransport定义了一个方法getPeer ,它向您公开传输对象所代表的连接的“对等”地址。 self.transport.getPeer() returns an object that represents that address. self.transport.getPeer()返回表示该地址的对象。 The exact shape of that object depends on what kind of connection you have. 该对象的确切形状取决于您拥有的连接类型。

You asked how can I choose particular client on basis of ip address . 您问我如何根据IP地址选择特定客户端 If it is really the case that data flowing through your system has its destination explicitly specified by an IP address then you can use getPeer to find a connection that matches the required address. 如果确实存在流经系统的数据的目的地由IP地址明确指定的情况,则可以使用getPeer查找与所需地址匹配的连接。

However, it is much more common to stop using the connection's endpoint's addresses after you've set up the connection. 但是,在建立连接后停止使用连接的端点地址更为常见。 IP address information tends to be unreliable because of the degree to which NAT has been deployed. 由于NAT的部署程度,IP地址信息往往不可靠。 It is not always wrong to embed IP addresses in your application-level protocol but it is hard to think of examples where it is right. 它并不总是错在你的应用层协议嵌入IP地址,但它很难想象的例子,其中它是正确的。

Fortunately, the alternative is even easier. 幸运的是,替代方案更容易。 self.transport already represents a certain connection. self.transport 代表某种连接。 This is just a regular old Python object. 这只是一个普通的旧Python对象。 Once you know which two clients are meant to be exchanging data with each other you only need to use the objects to get data sent to the right place. 一旦您知道哪两个客户端要彼此交换数据,您只需要使用这些对象将数据发送到正确的位置。

For example, if you have a server that accepts exactly four connections and a factory which saves a reference to the IProtocol provider it creates to handle each of those connections (think about that for a minute: since each ITransport provider represents exactly one connection, what must it mean about protocol objects that have a transport attribute that refers to one of those? If two protocol objects referred to the same transport... And a single protocol object's transport attribute can't possible refer to more than one object...) as attributes one , two , three , four then when one of those protocol objects implemented its dataReceived method like this: 例如,如果您的服务器只接受四个连接,并且工厂保存对IProtocol 提供程序的引用,则会创建它来处理每个连接(请考虑一下这一点:因为每个ITransport提供程序只代表一个连接,它是否意味着具有transport属性引用其中一个的协议对象?如果两个协议对象引用相同的传输...并且单个协议对象的transport属性不可能引用多个对象... )作为属性onetwothreefour然后当其中一个协议对象实现其dataReceived方法时,如下所示:

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

This must necessarily be writing data to the fourth connection established to the server. 这必须将数据写入建立到服务器的第四个连接。 There is no explicit addressing in this example. 此示例中没有明确的寻址。 There is just careful use of certain Python objects. 只是小心使用某些Python对象。

Careful use of certain Python objects is the overall answer to this question. 仔细使用某些Python对象是这个问题的总体答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM