DHT TCP API с внутренним использованием UDP для обслуживания запросов (скрученный)

Не уверен, что это правильное название для моей проблемы, но вот оно: в настоящее время я реализую распределенную хеш-таблицу (DHT) с API, с которым можно связаться через TCP. Он может обслуживать несколько вызовов API, таких как PUT, GET, Trace, при прослушивании нескольких комбинаций IP/Port, например:

factory = protocol.ServerFactory()
factory.protocol = DHTServer
for ip in interfaces:
    for port in ports:
        reactor.listenTCP(int(port), factory, interface=ip)
        print ("Listening to: "+ ip +" on Port: "+port)
reactor.run() 

Теперь эти «внешние» вызовы API будут выполняться базовой реализацией DHT (Kademlia, Chord или Pastry). Эти базовые реализации DHT используют разные протоколы для связи друг с другом. Kademlia, например, использует RPC через UDP.

Протокол для TCP API (DHTServer в приведенном выше коде) имеет внутренний протокол DHT, подобный этому:

self.protocol = Kademlia(8088, [("192.168.2.1", 8088)])

Теперь, если клиент делает два отдельных запроса API друг за другом, я получаю это сообщение об ошибке во втором запросе:

line 197, in _bindSocket
raise error.CannotListenError(self.interface, self.port, le)
    twisted.internet.error.CannotListenError: Couldn't listen on any:8088: [Errno 10
    048] Normalerweise darf jede Socketadresse (Protokoll, Netzwerkadresse oder Ansc
    hluss) nur jeweils einmal verwendet werden.

Что в основном говорит о том, что каждый адрес сокета должен использоваться только один раз. Я не совсем уверен, но я думаю, это потому, что для каждого запроса API создается новый экземпляр протокола DHTServer, который, в свою очередь, также создает новый экземпляр Kademlia, и оба пытаются прослушивать один и тот же адрес. Но почему это так? Разве первый экземпляр протокола DHTServer не должен быть уничтожен после того, как будет обслужен первый запрос? Что я делаю неправильно? Есть ли лучший способ сделать это? Я только недавно начал работать с твистами, так что наберитесь терпения. Большое спасибо!


person puelo    schedule 14.08.2015    source источник


Ответы (2)


Я ничего не знаю о Twisted, но kademlia — это сетевая служба с отслеживанием состояния, которая должна поддерживать свою таблицу маршрутизации и все такое.

Рассмотрите возможность совместного использования одного экземпляра kademlia (и, следовательно, базового сокета UDP) для ваших запросов.

person the8472    schedule 17.08.2015

Мое решение состояло в том, чтобы написать свою собственную фабрику с уже предопределенным внутренним протоколом. Таким образом, я могу получить к нему доступ из каждого экземпляра, и он остается прежним.

person puelo    schedule 20.09.2015
comment
Это, вероятно, правильный путь, если вы правильно обрабатываете удаление и повторное добавление прослушивающего сокета. Это не будет работать с TCP, поскольку он ориентирован на соединение, но для UDP все должно быть в порядке. - person Glyph; 06.10.2015