获取 Twisted 服务器的 IP 地址
Get Twisted server's IP address
如果我有一个 Twisted 服务器,我怎样才能找到它的 public-facing IP 地址?
以这个简单的回显服务器为例:
from twisted.internet import protocol, reactor, endpoints
class Echo(protocol.Protocol):
def dataReceived(self, data):
self.transport.write(data)
class EchoFactory(protocol.Factory):
def buildProtocol(self, addr):
return Echo()
server_endpoint = endpoints.serverFromString(reactor, "tcp:1234")
listening_port_deferred = server_endpoint.listen(EchoFactory())
reactor.run()
我期待 server_endpoint.getHost()
,但我看不到 TCP4ServerEndpoint
提供任何有用的东西。
通过在reactor.run()
之前添加以下行,我们可以看到服务器正在监听所有接口(0.0.0.0):
def print_host(listening_port):
print("listening_port.getHost():", listening_port.getHost())
listening_port_deferred.addCallback(print_host)
输出listening_port.getHost(): IPv4Address(type='TCP', host='0.0.0.0', port=1234)
。但这对我们获取服务器网络接口的 IP 地址没有帮助。
我们可以通过在buildProtocol():
的第一行添加以下内容来获取客户端的IP地址
print("Client's address:", addr.host)
但这只给了我们客户的地址。
我应该如何获取服务器的 IP 地址?
Twisted 会告诉您绑定服务器的地址,只使用您在侦听端口上找到的方法 getHost
。不幸的是,您发现它有很大的局限性,即当服务器侦听所有本地地址 (INADDR_ANY
) 时,它会为您提供 0.0.0.0
([=12= 的规范 IPv4 点分四边形表示) ]).
发生这种情况时,您必须离开 Twisted。我发现 netifaces 包对此非常有用。来自文档:
>>> netifaces.interfaces()
['lo0', 'gif0', 'stf0', 'en0', 'en1', 'fw0']
>>> >>> addrs = netifaces.ifaddresses('lo0')
>>> addrs[netifaces.AF_INET]
[{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}]
通过将此信息与 0.0.0.0
表示“所有本地地址”的观察相结合,您可以计算出服务器将接受哪些本地地址的连接。
感谢 notorious 的评论,我意识到服务器的 IP 地址只有在客户端连接后才可用。然而,正如 Jean-Paul 指出的那样,这个 IP 地址不一定是面向 public 的,很可能位于 NATing 路由器之后。
要获取给定连接的服务器 IP 地址,我们可以使用 Protocol
class. This is documented in the ITransport
接口的 transport
属性中的 getHost()
方法。
比如我们在原题的Echo
协议class中加入如下方法,每次客户端连接时,服务器端都会打印出使用过的IP地址。
def connectionMade(self):
print("IP address of host given connection:", self.transport.getHost())
因此,例如,如果您从服务器 运行 所在的同一台计算机连接,您将看到:
IP address of host given connection: IPv4Address(type='TCP', host='127.0.0.1', port=1234)
但是,如果您从同一网络上的另一台计算机连接,您可能会看到:
IP address of host given connection: IPv4Address(type='TCP', host='192.168.5.103', port=1234)
如果我有一个 Twisted 服务器,我怎样才能找到它的 public-facing IP 地址?
以这个简单的回显服务器为例:
from twisted.internet import protocol, reactor, endpoints
class Echo(protocol.Protocol):
def dataReceived(self, data):
self.transport.write(data)
class EchoFactory(protocol.Factory):
def buildProtocol(self, addr):
return Echo()
server_endpoint = endpoints.serverFromString(reactor, "tcp:1234")
listening_port_deferred = server_endpoint.listen(EchoFactory())
reactor.run()
我期待 server_endpoint.getHost()
,但我看不到 TCP4ServerEndpoint
提供任何有用的东西。
通过在reactor.run()
之前添加以下行,我们可以看到服务器正在监听所有接口(0.0.0.0):
def print_host(listening_port):
print("listening_port.getHost():", listening_port.getHost())
listening_port_deferred.addCallback(print_host)
输出listening_port.getHost(): IPv4Address(type='TCP', host='0.0.0.0', port=1234)
。但这对我们获取服务器网络接口的 IP 地址没有帮助。
我们可以通过在buildProtocol():
print("Client's address:", addr.host)
但这只给了我们客户的地址。
我应该如何获取服务器的 IP 地址?
Twisted 会告诉您绑定服务器的地址,只使用您在侦听端口上找到的方法 getHost
。不幸的是,您发现它有很大的局限性,即当服务器侦听所有本地地址 (INADDR_ANY
) 时,它会为您提供 0.0.0.0
([=12= 的规范 IPv4 点分四边形表示) ]).
发生这种情况时,您必须离开 Twisted。我发现 netifaces 包对此非常有用。来自文档:
>>> netifaces.interfaces()
['lo0', 'gif0', 'stf0', 'en0', 'en1', 'fw0']
>>> >>> addrs = netifaces.ifaddresses('lo0')
>>> addrs[netifaces.AF_INET]
[{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}]
通过将此信息与 0.0.0.0
表示“所有本地地址”的观察相结合,您可以计算出服务器将接受哪些本地地址的连接。
感谢 notorious 的评论,我意识到服务器的 IP 地址只有在客户端连接后才可用。然而,正如 Jean-Paul 指出的那样,这个 IP 地址不一定是面向 public 的,很可能位于 NATing 路由器之后。
要获取给定连接的服务器 IP 地址,我们可以使用 Protocol
class. This is documented in the ITransport
接口的 transport
属性中的 getHost()
方法。
比如我们在原题的Echo
协议class中加入如下方法,每次客户端连接时,服务器端都会打印出使用过的IP地址。
def connectionMade(self):
print("IP address of host given connection:", self.transport.getHost())
因此,例如,如果您从服务器 运行 所在的同一台计算机连接,您将看到:
IP address of host given connection: IPv4Address(type='TCP', host='127.0.0.1', port=1234)
但是,如果您从同一网络上的另一台计算机连接,您可能会看到:
IP address of host given connection: IPv4Address(type='TCP', host='192.168.5.103', port=1234)