Java:指定传出连接的本地地址

Java:指定传出连接的本地地址,java,proxy,urlconnection,virtual-ip-address,Java,Proxy,Urlconnection,Virtual Ip Address,我们有许多服务器承载多个IP地址。其他的是所谓的虚拟IP VIP 我们希望使Java应用程序能够建立一个传出连接,该连接将指定的虚拟IP而不是主机IP地址列为源地址 这是我们尝试过的。InetAddressgetByAddress中列出的ip地址是虚拟ip地址。属性url是用户指定的要连接到的目标url public void attemptConnection() { try { Proxy proxy = new Proxy(Proxy.Type.HTTP, ne

我们有许多服务器承载多个IP地址。其他的是所谓的虚拟IP VIP

我们希望使Java应用程序能够建立一个传出连接,该连接将指定的虚拟IP而不是主机IP地址列为源地址

这是我们尝试过的。InetAddressgetByAddress中列出的ip地址是虚拟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-msimpleHttpServer,然后尝试连接

如果我们在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)
我将深入研究SocketsetSocketImplFactory,看看是否可以通过自定义每个创建的套接字来解决这个问题

问题在于,SocketsetSocketImplFactory和URL.setURLStreamHandlerFactory都允许您覆盖默认实现,但不允许您访问默认实现,因此它们似乎都是完全或无覆盖。当您只希望在顶部添加逻辑时,这是非常烦人的

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();