Java: указание локального адреса для исходящего соединения

У нас есть много серверов, которые размещают несколько IP-адресов. Дополнительные - это так называемые виртуальные IP-адреса ("VIP").

Мы бы хотели, чтобы приложение Java установило исходящее соединение, в котором в качестве адреса источника указан виртуальный IP-адрес, а не IP-адрес хоста.

Вот что мы попробовали. IP-адрес, указанный в InetAddress#getByAddress это виртуальный IP-адрес. Недвижимость url заданный пользователем целевой URL для подключения.

public void attemptConnection() {
  try {
    Proxy proxy = new Proxy(Proxy.Type.HTTP,
        new InetSocketAddress(InetAddress.getByAddress(new byte[]{(byte)10,(byte)252,(byte)47,(byte)33}), 0));
    final URL _url = new URL(url);
    final URLConnection conn = _url.openConnection(proxy);
    BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String inputLine;
    while ((inputLine = in.readLine()) != null) {
      System.out.println(inputLine);
      in.close();
    }
  } catch (Exception e) {
    e.printStackTrace();
  }
}

Код выше был смоделирован на этот ответ

Мы тестируем это с Python SimpleHTTPServer, просто бег python -m SimpleHTTPServer затем пытается подключиться.

Если мы не используем прокси в нашем Java-коде, то соединение работает правильно.

Однако, как только VIP-прокси определен, мы получаем отказ в соединении:

java.net.ConnectException: Connection refused
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:327)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:193)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180)
        at java.net.Socket.connect(Socket.java:546)
        at java.net.Socket.connect(Socket.java:495)
        at sun.net.NetworkClient.doConnect(NetworkClient.java:178)
        at sun.net.www.http.HttpClient.openServer(HttpClient.java:409)
        at sun.net.www.http.HttpClient$2.run(HttpClient.java:457)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.net.www.http.HttpClient.privilegedOpenServer(HttpClient.java:454)
        at sun.net.www.http.HttpClient.openServer(HttpClient.java:521)
        at sun.net.www.http.HttpClient.<init>(HttpClient.java:240)
        at sun.net.www.http.HttpClient.New(HttpClient.java:321)
        at sun.net.www.http.HttpClient.New(HttpClient.java:338)
        at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:935)
        at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:914)
        at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:801)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1139)
        at com.ocado.dsi.ConnectToUrl.attemptConnection(ConnectToUrl.java:38)
        at com.ocado.dsi.ConnectToUrl.run(ConnectToUrl.java:56)
        at com.ocado.dsi.ConnectToUrl.main(ConnectToUrl.java:64)

Есть идеи почему?

Обновить

При указании локального адреса на сокете процесс работает нормально.

Я настраиваю простой сервер сокетов Python, прослушивающий порт 8000 так же, как SimpleHTTPServer используется выше, делает. Подключение к нему из Java с использованием сокета с желаемым локальным адресом работало должным образом: сервер Python распознал адрес источника входящего соединения, как это определено пользователем.

Socket s = new Socket(InetAddress.getByAddress(new byte[]{(byte)10,(byte)252,(byte)47,(byte)33}), 8000, InetAddress.getByAddress(new byte[]{(byte)10,(byte)97,(byte)5,(byte)147}), 0);
s.close();

Я собираюсь копаться в Socket#setSocketImplFactory чтобы увидеть, можно ли решить проблему, настроив каждый созданный сокет.

Проблема в том, что оба Socket#setSocketImplFactory а также URL.setURLStreamHandlerFactory Позволяет вам переопределить реализацию по умолчанию, но не дает вам доступа к реализации по умолчанию, так что, похоже, они переопределяют все или ничего. Это очень раздражает, когда вы только хотите добавить логику сверху.

0 ответов

Другие вопросы по тегам