getLocalAddress возвращает 127.0.0.1 на подключенном сокете

68
8

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

Проблема заключается в том, что вызов Socket.getLocalAddress(). GetHostAddress() возвращается неправильно (ТОЛЬКО В НЕСКОЛЬКИХ СЛУЧАЕ) 127.0.0.1, тогда как в большинстве случаев/ПК он отлично работает...

Вот фрагмент используемого кода:

public static String getLocalIPAddress(String serverIP, int port) throws UnknownHostException
{
System.out.println("Executing getLocalIPAddress on "+serverIP + ":" + port);
InetAddress inetAddress = InetAddress.getLocalHost();
String ipAddress = inetAddress.getHostAddress();
try {
Socket s = new Socket(serverIP, port);
ipAddress = s.getLocalAddress().getHostAddress();
System.out.println("Local IP : "+s.getLocalAddress().getHostAddress());
s.close();
} catch (Exception ex) {}
return ipAddress;
}

Результат, который я получаю в следующем случае,

Executing getLocalIPAddress...
Executing getLocalIPAddress on 1.2.3.4:80
Local IP : 6.7.8.9

Результат, который я получаю в случае отказа, равен

Executing getLocalIPAddress...
Executing getLocalIPAddress on 1.2.3.4:80
Local IP : 127.0.0.1

Обратите внимание, что в случае отказа он не прошел через исключение.

Любые советы очень ценятся.

спросил(а) 2020-04-04T00:11:19+03:00 3 месяца назад
1
Решение
108

Socket.getLocalAddress() возвращает локальный адрес, к которому привязан сокет. Поэтому "127.0.0.1" предполагает, что сокет ограничен интерфейсом loopback. Аналогично, "6.7.8.9" означает, что сокет ограничен другим интерфейсом клиента, который имеет адрес "6.7.8.9".

Один из способов указать локальный адрес и порт на стороне клиента, используемые для привязки, - использовать следующий конструктор

    Socket(InetAddress address, int port, InetAddress localAddr, int localPort)

В приведенном примере вы можете использовать

    Socket s = new Socket(serverIP, port, InetAddress.getLocalHost(), 0);

указать IP-адрес локального хоста (а не адрес циклы) для связывания сокетов клиента. Я проверил приведенный выше пример, и он работает.

ответил(а) 2020-04-04T00:27:30.828953+03:00 3 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема