如果我有一台Twisted服务器,如何找到其面向公众的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地址?
答案 0 :(得分:1)
Twisted会仅使用在侦听端口上找到的方法getHost
告诉您将服务器绑定到的地址。不幸的是,您发现它有一个很大的限制,那就是当服务器侦听所有本地地址(INADDR_ANY
)时,它会给您0.0.0.0
({{1}的规范IPv4点分四进制表示形式) }。
发生这种情况时,您必须离开Twisted。我发现netifaces软件包对此非常有用。从文档中:
INADDR_ANY
通过将此信息与观察到的>>> 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'}]
表示“所有本地地址”相结合,可以确定服务器将在其上接受连接的本地地址。
答案 1 :(得分:1)
由于臭名昭著的评论,我意识到服务器的IP地址仅在客户端连接后才可用。但是,正如让·保罗指出的那样,此IP地址不一定是面向公众的,并且很可能在NATing路由器后面。
要获取给定连接的服务器IP地址,我们可以使用Protocol
类的getHost()
属性中的transport
方法。在ITransport
界面中对此进行了记录。
例如,如果我们将以下方法添加到原始问题的Echo
协议类中,则每次客户端连接时,服务器都会打印出使用的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)