Такс... на чём мы тут остановились... Продолжаем поднимать домашнюю сеть. Типа домашний сервер))
Первый раз пишу на Java... поэтому пока всё не идеально))
Маршрутизация.Есть роутер, сервер, комп, другие устройства...
Роутер получает IP от провайдера по DHCP.
Все устройства в доме подключены к роутеру и получает IP от роутера по DHCP.
В роутере можно пробросить порты. Но мы просто включим режим DMZ. Так проще))
Нарисуем схему, всё подключим и протестируем))
- 1.jpg
- (60.57 KiB) Скачиваний: 301
Запускаем Java приложение и смотрим как бегают пакеты по нашей сети...
Вариант 1. (подключение из локальной сети LAN).
-телефон получает 192.168.0.101 (по DHCP от роутера).
-телефон 192.168.0.101 отправляет пакет серверу 192.168.0.3.
-сервер смотрит IP отправителя (Source IP Address) и видит IP телефона 192.168.0.101.
-сервер отправляет пакет обратно телефону 192.168.0.101.
Всё работает.
Вариант 2. (подключение из внешней сети WAN).
-телефон получает 1.2.3.4 (по DHCP от провайдера).
-телефон 1.2.3.4 отправляет пакет роутеру 10.0.0.8.
-роутер (NAT) транслирует пакет серверу 192.168.0.3.
-сервер смотрит IP отправителя (Source IP Address) и видит IP телефона 1.2.3.4.
-сервер отправляет пакет обратно роутеру (NAT).
-роутер (NAT) транслирует пакет обратно телефону 1.2.3.4.
Всё работает.
Но тут есть одна проблемка. )) Чтобы всё работало, надо указать телефону где мы находимся: в LAN или WAN сети.
Для этого в Java приложении добавим кнопочку "LAN/WAN".
Зачем это надо ? Это видно из следующей схемы. Что будет если переключить кнопочку в режим WAN и подключиться к домашней сети LAN:
- 2.jpg
- (71.02 KiB) Скачиваний: 286
Вариант 3. (подключение из локальной сети LAN в режиме WAN).
-телефон получает 192.168.0.101 (по DHCP от роутера).
-телефон 192.168.0.101 отправляет пакет роутеру 10.0.0.8.
-роутер (NAT) транслирует пакет серверу 192.168.0.3.
-сервер смотрит IP отправителя (Source IP Address) и видит IP роутера 10.0.0.8.
-сервер отправляет пакет обратно... РОУТЕРУ !!! 10.0.0.8. !!!
-роутер (NAT) транслирует пакет серверу 192.168.0.3.
-сервер смотрит IP отправителя (Source IP Address) и видит IP роутера 10.0.0.8.
-сервер отправляет пакет обратно... РОУТЕРУ !!! 10.0.0.8. !!!
-роутер (NAT) транслирует пакет серверу 192.168.0.3.
-сервер смотрит IP отправителя (Source IP Address) и видит IP роутера 10.0.0.8.
-сервер отправляет пакет обратно... РОУТЕРУ !!! 10.0.0.8. !!!
...
Процесс повторяется бесконечно )) На языке сисадминов получаем "кольцо"... )) Класс))
А что делать в такой ситуации ? Вариантов много...
1 - сначала просто добавил блокировку IP в сервере. Если сервер видит 10.0.0.8, то сервер не отвечает.
Не лучшая идея.
2 - добавил IP отправителя (Source IP Address) в сам пакет.
Теперь сервер смотрит не IP отправителя (Source IP Address) в Ethernet пакете, а IP в самом пакете.
Всё работает.
На этом сриншоте видно как телефон (в нашем случае ПК) обменивается пакетами с сервером.
Стандартные UDP пакеты... с контрольной суммой (CRC-16). Ничего особенного))
В пакете вручную прописываем IP телефона 192.168.0.101.
Сервер берёт адрес отправителя (Source IP Address) из пакета.
Сервер возвращает нам свой IP адрес (сервер) и IP нашего телефона 192.168.0.101 (клиент) .
)) Можно использовать наш сервер для определения IP, вместо сайта
https://2ip.ru/ ))
А тут мы подключились к серверу в режиме WAN.
Сервер вернул нам IP роутера 10.0.0.8.
Всё это замечательно, но прописывать вручную IP телефона 192.168.0.101 не лучшая идея. Потому что телефон получает 192.168.0.101 (по DHCP от роутера). Да и сама кнопка "LAN/WAN" мне тоже не нравится.
Тогда сделаем по другому)) Идея простая. Java может определить IP телефона, который он получает от роутера. Затем добавить в пакет и отправить серверу. Тогда кнопка "LAN/WAN" не нужна. ))
Всё работает.
P.S. Придумал протокол обхода NAT. (или по-простому "как обмануть роутер"). ))
А вообще пора уже выкинуть все эти NAT-ы... И вообще пора уже переходить на IPv6. Тогда и NAT-ы не нужны))