Обход Java nat для приложения чата

Я пытаюсь создать приложение чата на Java для своего сетевого класса. На данный момент я застрял, пытаясь подключиться к кому-то за другим маршрутизатором. Прямо сейчас у меня есть проект: у меня есть клиентская программа и серверная программа. Клиентские программы сначала входят в серверную программу, которая регистрирует их IP-адрес и порт в базе данных, а затем сервер возвращает им список их друзей с их IP-адресами и портами. Затем клиент закрывает соединение с сервером и пытается подключиться к другому клиенту, используя информацию, которую сервер отправил обратно. Пока моя программа работает только с подключением к серверу и получением IP-адреса и порта друзей, но когда я использую эти значения для подключения к другому клиенту, я не могу подключиться.

socket = new Socket();
socket.setReuseAddress(true);
socket.setKeepAlive(true);
socket.setSoLinger(true, 10);
socket.bind(new InetSocketAddress(Port));
socket.connect(new InetSocketAddress(host, SERVER_PORT));
reusePort = socket.getLocalPort(); 

Выше фрагмент кода Java, используемый для подключения к серверу, ниже - то, что я делаю на стороне клиента.

ss = new ServerSocket(reusePort);

Итак, теперь технически я слушаю тот же порт, который использовал для подключения к серверу, с которого вошел в систему и который может быть получен другим клиентом и находится в таблице NAT с моим IP-адресом и портом. Я не уверен, что мне не хватает, есть ли какой-то протокол или что-то, что я должен сделать. Я посмотрел на пробивку отверстий TCP и UDP, но я не уверен, как это на самом деле выполняется или как это реализовать.

Мы ценим любые предложения.


person DarkLazar    schedule 10.04.2013    source источник
comment
Я вижу, вы приняли ответ, но, похоже, вы хотите разобраться с дыркой в ​​дырке. Принятый ответ на самом деле не отвечает на ваш вопрос, а вместо этого предлагает вам позволить всей информации вашего приложения проходить через ваш сервер, и кажется, что вы хотите напрямую подключать своих клиентов.   -  person Mattias F    schedule 01.11.2014
comment
эй, ты нашел свой ответ. пожалуйста, помогите мне. Я с той же проблемой.   -  person Sagar Nayak    schedule 08.03.2016
comment
Возможный дубликат библиотеки STUN, TURN, ICE для Java   -  person Rajat    schedule 19.04.2017


Ответы (2)


Если вы хотите отправить сообщение, вам необходимо настроить переадресацию портов на любом устройстве, которое действует как сервер (любое устройство, которое создает сервер сокетов). Переадресация портов выполняется на маршрутизаторе. Причина, по которой вы не можете подключиться к другому клиенту, заключается в том, что он скрыт за брандмауэром своего маршрутизатора. Их адрес для остального мира на самом деле является адресом маршрутизатора, а не их физического компьютера. В своей локальной сети у них другой адрес, чем тот, который видит остальной мир, и маршрутизатор определяет, какие сообщения из внешнего мира необходимо отправить клиенту, на основе таблицы трансляции адресов.

Учитывая вашу архитектуру, это будет означать, что всем клиентам необходимо, чтобы их маршрутизаторы выполняли переадресацию портов, что, конечно, невозможно (представьте, что gtalk или цель требуют, чтобы пользователи выполняли переадресацию портов).

Более распространенная архитектура заключается в том, что Сервер выполняет работу по ретрансляции сообщений подключенным клиентам и поддерживает таблицы для поиска, чьи с кем общаются. Таким образом, существует единственный сервер, которому потребуется статический IP-адрес (или будет перенаправлен порт), и все пользователи будут просто клиентами, которые подключаются к сокету сервера и читают сообщения от него.

Фактический код, описывающий вторую архитектуру, см. На странице http://pirate.shu.edu/~wachsmut/Teaching/CSAS2214/Virtual/Lectures/chat-client-server.html. Затем машине, на которой выполняется код сервера, либо нужен статический IP-адрес, либо, если он находится за маршрутизатором, требуется перенаправление трафика с порта, который он прослушивает.

Таким образом, в коде сервера вы будете привязаны к IP-адресу, назначенному вашим маршрутизатором (что-то вроде 192.168.1.2 на каком-то порте, скажем, 5000). Затем перейдите на страницу конфигурации маршрутизатора (это может быть 192.168.1.1, см. http://www.wikihow.com/Port-Forward/Open-Ports-on-a-Linksys-Router) и перенаправьте порт 5000 на адрес 192.168.1.2.

person Anil Vaitla    schedule 10.04.2013
comment
Спасибо тигру! На данный момент у меня есть порт моего сервера, перенаправленный на X за моим маршрутизатором, я думаю о переключении на вторую архитектуру, которую вы предложили (спасибо за ссылку, это может быть сложно отсеять, хотя иногда Google lol) и чтобы каждый клиент поддерживал единственное соединение с сервером, и сервер затем пересылает им что-либо через него. Тем не менее, я собираюсь немного повозиться с тем, что у меня есть, а затем переключаться, когда у меня заканчивается время. Спасибо за помощь. - person DarkLazar; 11.04.2013
comment
Итак, вы говорите, что, поскольку мы не можем перейти к каждому маршрутизатору, мы проходим через него и выполняем переадресацию портов. поэтому мы должны использовать сервер и позволить ему делать свою работу. (пожалуйста, поправьте меня, если я ошибаюсь). так что именно будет делать сервер? пожалуйста, простите меня, если мой вопрос странный, я новичок в нетворкинге. - person Sagar Nayak; 08.03.2016
comment
@DarkLazar Так работают торрент-клиенты? Или они используют какой-то другой способ добиться этого? Есть ли более простой способ реализовать это? (как библиотека) - person goodbytes; 16.04.2016

Протокол интерактивного установления соединения (ICE) объединяет различные утилиты обхода NAT, такие как протоколы STUN и TURN, чтобы предложить мощный механизм, который позволяет протоколам на основе предложений / ответов, таким как SIP и XMPP, проходить через NAT.

Этот проект предоставляет Java-реализацию протокола ICE, который будет использоваться как приложениями SIP, так и XMPP. Проект также предоставляет такие функции, как совместное использование сокетов и поддержку Pseudo TCP.

ice4j поддерживается сообществом Jitsi.

ice4j

person Rajat    schedule 19.04.2017