Java P2P Chat Использование Stun [duplicate]

Добавление к ответу @Lombo

Когда вам нужно переопределить equals ()?

По умолчанию реализация equals () объекта равна

public boolean equals(Object obj) {
        return (this == obj);
}

, что означает, что два объекта будут считаться равными, только если они имеют одинаковый адрес памяти, который будет истинным, только если вы сравниваете объект с самим собой.

Но вы можете хотите рассмотреть два объекта одинаково, если они имеют одно и то же значение для одного или нескольких своих свойств (см. пример, приведенный в ответе @Lombo).

Итак, вы переопределите equals() в этих ситуациях, и вы дадите свои собственные условия для равенства.

Я успешно применил equals (), и он отлично работает. Так почему же они просят переопределить hashCode ()?

Хорошо. Пока вы не используете «Коллекции на основе хэша» определенный класс, это нормально. Но в будущем вы можете захотеть использовать HashMap или HashSet, и если вы не override и «правильно реализуете» hashCode () , эта коллекция на основе хэша не будет

Только переопределение равно (добавление к ответу @Lombo)

myMap.put(first,someValue)
myMap.contains(second); --> But it should be the same since the key are the same.But returns false!!! How?

Прежде всего, HashMap проверяет, является ли хэш-код second совпадает с first.

Но здесь hashCode отличается для этих двух объектов (потому что у них есть другой адрес памяти - от реализации по умолчанию). Если только значения совпадают, он будет проверять равенство в том же ведре.

Поэтому даже не стоит проверять равенство.

Если у вас есть точка останова внутри вашего переопределенного метода equals (), она не будет входить, если у них разные хэш-коды. contains() проверяет hashCode(), и только если они одинаковы, он будет вызывать ваш метод equals().

Почему мы не можем сделать проверку HashMap равным во всех ведрах? Поэтому мне не нужно переопределять hashCode () !!

Тогда вам не хватает точки из Hash-based Collections. Рассмотрим следующее:

Your hashCode() implementation : intObject%9.

Ниже приведены ключи, хранящиеся в форме ведер.

Bucket 1 : 1,10,19,... (in thousands)
Bucket 2 : 2,20,29...
Bucket 3 : 3,21,30,...
...

Скажите, вы хотите знать, содержит ли карта ключ 10. Вы хотите найти все ведра? или Вы хотите искать только одно ведро?

На основании hashCode вы бы определили, что если 10 присутствует, он должен присутствовать в Bucket 1. Таким образом, будет поиск только Bucket 1 !!

30
задан Nalaka526 8 June 2015 в 11:26
поделиться

5 ответов

Связность P2P в двух словах. Предположим, мы говорим о UDP здесь. Следующие шаги также могут применяться к TCP с некоторыми настройками.

  1. Перечислите все локальные IP-адреса (обычно только 1). Создайте сокет UDP для определенного номера порта ** для каждого адаптера с IP-адресом.
  2. Для каждого сокета, созданного на шаге 1, обратитесь к серверу STUN или TURN с тем же сокетом, чтобы обнаружить внешний IP-адрес и узнать, что внутренний номер порта отображает вне NAT (это не всегда одно и то же значение порта). То есть ваш локальный адрес 192.168.1.2:4900 может быть 128.11.12.13:8888 внешнему миру. И некоторые NAT не всегда используют одно и то же сопоставление портов при использовании одного и того же локального порта для других IP-адресов. TURN также предоставит вам «адрес реле». Вы также можете использовать UPNP для получения адреса, сопоставленного портам, с вашего маршрутизатора, если он поддерживает этот протокол.
  3. Через службу рандеву (SIP, XMPP, мгновенное сообщение, веб-сервис, электронная почта, чашки со строками) , опубликуйте свой список кандидатов на адрес в службу или отправьте уведомление другому клиенту, который говорит: «Эй, я хочу связаться с вами». Это сообщение включает в себя все «адресаты кандидатов» (пары ip и портов), собранные в шагах 1 и 2.
  4. Удаленный клиент, получив приглашение для подключения, также выполняет шаги 1 и 2 выше. Затем отправляет свой список кандидатов по тому же каналу, на который он получил список кандидатов приглашения.
  5. Шаг штамповки отверстий. Оба клиента начинают отправлять тестовые сообщения через UDP другим кандидатам на адреса других сторон и прослушивать одни и те же сообщения на своем конце. Всякий раз, когда принимаются сообщения, возвращайте обратно адрес, с которого он пришел. В конце концов, клиенты обнаружат, что у них есть пара адресов, которые они могут надежно отправлять дейтаграммы. Как правило, одна конечная точка принимает окончательное решение о том, по какой адресу (сокетам) адреса связывается, и протокол облегчает эту конечную точку, сообщая другой конечной точке это решение.

** - обычно лучше всего не делать этого полагаться на хорошо известный порт для клиентов P2P. Поскольку два клиента за одним и тем же NAT или брандмауэром вряд ли смогут использовать ваше программное обеспечение в то же время.

Ниже приведен краткий обзор некоторых технологий для изучения.

STUN - простой сервер и протокол для клиентов за NAT / маршрутом, чтобы узнать, каковы их внешние сопоставления IP и портов.

TURN - это расширение для STUN, но поддерживает ретрансляцию для сценариев подключения P2P, где брандмауэры и NAT предотвращают прямые подключения.

ICE - это набор шагов, с помощью которых STUN и TURN используются для настройки соединения P2P , ICE является формальным протоколом для шагов 1-5 выше. Два превосходных набора слайдов на ICE здесь здесь и здесь .

WebRTC является вариантом стандарта ICE в качестве справочной библиотеки для создания сеансов P2P с помощью STUN и TURN.

UPNP + Протокол интернет-шлюза - Некоторые маршрутизаторы поддерживают это для хостов для автоматического получения сопоставлений портов.

libnice - это библиотека C с открытым исходным кодом для Linux (и может работать на Windows), которая реализует ICE.

libjingle - еще одна реализация ICE ( в C ++) из Google. Для Windows и Linux.

PJNATH - это библиотека в наборе библиотек кодирования PJSIP . Это хорошая реализация стека ICE (код C) и была перенесена на множество платформ. (Windows, Linux, Mac, iOS, Symbian и вскоре Android).

И, наконец, у меня есть вопиющий штепсель для вас, чтобы использовать мою базу кода сервера STUN .

95
ответ дан Steve Lorimer 26 August 2018 в 08:31
поделиться

Я бы использовал технологию WebRTC в качестве платформы с открытым исходным кодом для такого приложения.

Официальный сайт

На самом деле это проект с открытым исходным кодом, который поддерживает все необходимые для одноранговых технологий из коробки:

  • ICE и STUN (обход NAT)
  • DTLS и SRTP (безопасность)
  • AVPF для качества потоковой передачи.
2
ответ дан ankitr 26 August 2018 в 08:31
поделиться

В некоторых случаях есть решения, см. UPnP: https://en.wikipedia.org/wiki/Universal_Plug_and_Play#NAT_traversal

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

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

EDIT: @David предложил этот вопрос SO для библиотеки .NET для UPnP: Есть ли библиотека UPnP для .NET (C # или VB.NET)?

4
ответ дан Community 26 August 2018 в 08:31
поделиться

У вас есть еще одна опция, которая является Протокол сопоставления NAT-портов (NAT-PMP) NAT-PMP широко используется приложениями VoIP, такими как клиенты Skype или BitTorrent P2P.

0
ответ дан loretoparisi 26 August 2018 в 08:31
поделиться

Это может быть немного сложнее, чем то, что вы ищете, но TCP Hole Punching - это метод, который должен работать. http://en.wikipedia.org/wiki/TCP_hole_punching

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

1
ответ дан Matthew 26 August 2018 в 08:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: