Получить IP-адрес Twisted сервера - PullRequest
1 голос
/ 13 июля 2020

Если у меня Twisted сервер, как я могу найти его publi c 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-адресом сетевого интерфейса сервера.

Мы можем получить IP-адрес клиента, добавив следующую строку в качестве первой строки buildProtocol():

print("Client's address:", addr.host)

Но это дает нам только адрес клиента.

Как мне получить IP-адрес сервера?

Ответы [ 2 ]

1 голос
/ 14 июля 2020

Благодаря пресловутому комментарию я понял, что IP-адрес сервера доступен только после подключения клиента. Однако, как указывает Жан-Поль, этот IP-адрес не обязательно обращен к публике c и вполне может находиться за маршрутизатором NAT.

Чтобы получить IP-адрес сервера для данного соединения, мы можем используйте метод getHost() из атрибута transport класса Protocol. Это задокументировано в интерфейсе 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)

1 голос
/ 14 июля 2020

Twisted сообщит вам адрес, к которому вы привязали сервер, используя только найденный вами метод, getHost на порте прослушивания. К сожалению, у него есть большое ограничение, которое вы обнаружили, а именно: когда сервер прослушивает все локальные адреса (INADDR_ANY), он дает вам 0.0.0.0 (каноническое представление IPv4 в виде четырех точек INADDR_ANY).

Когда это произойдет, вы должны go за пределами 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 означает «все локальные адреса», вы можете выяснить, какие локальные адреса сервер будет принимать соединения.

...