Сокет, привязанный к адресу, не может подключиться к прослушивателю, за исключением привязки к 127.0.0.1 в Win XP

#java #sockets #windows-xp

#java #сокеты #windows-xp

Вопрос:

Я создал сокет и привязал его к 127.0.0.254, а затем попытался подключиться к HttpListener на 0.0.0.0 443, используя

 socket= new Socket();
socket.bind("127.0.0.254:0");
socket.connect("127.0.0.1",443);
 

При подключении происходит сбой с исключением «Нет маршрута к хосту»
Тот же блок кода отлично работает в win 8.

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ:

Я привязываю его к 0. Моя проблема в том, что я проверяю прослушиватель каждые 5 минут, чтобы проверить, работает ли он. Для этого я попытался привязать сокет к адресу .254, а затем определить, является ли он зондом или реальным, по адресу сокета, пытающегося подключиться. Это не работает в XP, так как соединение с сокетом не удается. Но если я не свяжусь, сокет примет адрес 127.0.0.1, и я не смогу отличить. Есть ли обходной путь для моего сценария?

Комментарии:

1. Выполняется ли вызов socket.bind("127.0.0.254:0"); успешно? Вы проверяете его результат на сбой? Имеет ли машина bind() , на которой вы вызываете, настройку интерфейса 127.0.0.254 ?

2. Привязка выполняется без ошибок, я проверил. Сбой происходит только при подключении его к адресу 127.0.0.1 443. Прослушиватель, находящийся на 0.0.0.0 443, означает, что он получает любой IP-адрес на том же порту. По крайней мере, я так полагаю.

Ответ №1:

Я подозреваю, что XP неправильно обрабатывает адаптеры обратной связи в отношении диапазона адресов 127.x.y.z. Я подозреваю, что если вы подключитесь к 127.0.0.1 из другого сокета, привязанного к 127.0.0.1, все будет в порядке. Но вы используете тот же порт источника и назначения (443) в вашем примере.

Вам действительно нужно, чтобы клиентский порт также был на 443? Обычно для серверов (прослушивающего сокета) имеет смысл привязываться к хорошо известному порту, но клиенты могут привязываться к любому порту.

Следовательно, это должно работать для всех платформ:

 socket= new Socket();
socket.bind("127.0.0.1:0");
socket.connect("127.0.0.1",443);
 

Или, что еще лучше, не привязывайте явно. ОС обнаружит, что вы устанавливаете соединение с loopback, и неявно выполнит соответствующую привязку.

 socket= new Socket();
socket.connect("127.0.0.1",443);