Цель
Я делаю приложение чата для Android и в настоящее время тестирую с 2 телефонами, которые в конечном итоге должны работать для нескольких тысяч пользователей.
проблема
Я получаю исключение ConnectionException, в котором говорится, что «Отказано в соединении», когда два телефона пытаются соединиться друг с другом через сокеты.
Текущий дизайн
Каждый телефон запускает ServerSocket, вызывает метод accept (), ожидая подключения какого-либо Socket, и какой бы телефон ни отправлял сообщение первым, будет создан клиентский Socket. Я уверен, что IP-адреса, которые я использую, являются правильными (они фактически используют один и тот же внешний IP).
Я считаю, что проблема с портами. Я генерирую номер порта в случайном порядке, и если он бесплатен, я говорю ServerSocket s = new ServerSocket( randomPortNumber )
,
То, что я думаю, является источником проблемы
Проблема в том, что этот номер порта находится за маршрутизатором NAT. Поэтому, когда Socket пытается подключиться к ServerSocket, используя что-то вроде Socket socket = new Socket( ip, serverSocketRandomPortNumber )
, он попытается подключиться к маршрутизатору NAT и передать ему этот номер порта, который не будет работать, так как сам маршрутизатор не прослушивает этот порт, но телефон за маршрутизатором находится.
Вопросы и мысли
У меня вопрос, как мне справиться с этой проблемой?
Должен ли я изменить свой дизайн?
Если нужно, альтернативный дизайн, о котором я думаю, — это использовать один ServerSocket на веб-хосте и использовать его для перенаправления сообщений, отправляемых из клиентских сокетов в другие клиентские сокеты.
Я буду реализовывать на стороне сервера в php ссылки на что-то вроде этого:
http://php.net/manual/en/sockets.examples.php
И я бы все еще использовал Java для клиентской стороны.
Поскольку один из телефонов находится за маршрутизатором NAT, ничто не может инициировать подключение к нему, если на маршрутизаторе не включена переадресация портов (или некоторые другие методы).
Обычный способ реализации приложения чата состоит в том, что существует общий сервер, к которому будут подключаться все клиенты.
Вам не нужно писать свой собственный чат-сервер (если вы действительно этого не хотите). Я предлагаю использовать протокол XMPP. Список уже сделанных серверов Вот. На стороне клиента (Android) вы можете найти библиотеки, которые вы можете использовать Вот.
Других решений пока нет …