1

複数の 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)

理由はありますか?

アップデート

ソケットのローカル アドレスを直接指定すると、プロセスは正常に機能します。

上記で使用したのと同じように、ポート 8000 でリッスンする Python シンプル ソケット サーバーをセットアップします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#setSocketImplFactoryURL.setURLStreamHandlerFactoryデフォルトの実装をオーバーライドできるが、デフォルトの実装にアクセスできないことです。上にロジックを追加したいだけの場合、これは非常に面倒です。

4

0 に答える 0