Как я могу указать локальный адрес в соединении java.net.URL?

StackOverflow https://stackoverflow.com/questions/91678

  •  01-07-2019
  •  | 
  •  

Вопрос

Мой экземпляр Tomcat прослушивает несколько IP-адресов, но я хочу контролировать, какой исходный IP-адрес используется при открытии URLConnection.

Как я могу это указать?

Это было полезно?

Решение

Это должно сработать:

URL url = new URL(yourUrlHere);
Proxy proxy = new Proxy(Proxy.Type.DIRECT, 
    new InetSocketAddress( 
        InetAddress.getByAddress(
            new byte[]{your, ip, interface, here}), yourTcpPortHere));
URLConnection conn = url.openConnection(proxy);

И с вами покончено.Не забывайте аккуратно обрабатывать исключения и, конечно же, изменять значения в соответствии с вашим сценарием.

Ах, и я опустил инструкции по импорту

Другие советы

Используя Apache commons HttpClient, я также обнаружил, что работает следующее (удалено try / catch для ясности):

HostConfiguration hostConfiguration = new HostConfiguration();
byte b[] = new byte[4];
b[0] = new Integer(192).byteValue();
b[1] = new Integer(168).byteValue();
b[2] = new Integer(1).byteValue();
b[3] = new Integer(11).byteValue();

hostConfiguration.setLocalAddress(InetAddress.getByAddress(b));

HttpClient client = new HttpClient();
client.setHostConfiguration(hostConfiguration);
GetMethod method = new GetMethod("http://remoteserver/");
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
    new DefaultHttpMethodRetryHandler(3, false));
int statusCode = client.executeMethod(method);

if (statusCode != HttpStatus.SC_OK) {
    System.err.println("Method failed: " + method.getStatusLine());
}

byte[] responseBody = method.getResponseBody();
System.out.println(new String(responseBody));");

Тем не менее, мне все еще интересно, что произойдет, если шлюз IP-адреса не работает (в данном случае 192.168.1.11).Будет ли опробован следующий шлюз или он выйдет из строя?

Очевидным переносимым способом было бы установить прокси-сервер в URL.openConnection.Прокси-сервер может находиться на локальном хосте, тогда вы можете написать очень простой прокси, который привязывает локальный адрес клиентского сокета.

Если вы не можете изменить источник, к которому подключен URL-адрес, вы можете заменить URLStreamHandler либо при вызове конструктора URL, либо глобально через URL.setURLStreamHandlerFactory.Затем URLStreamHandler может делегировать обработчику http / https по умолчанию, изменяя вызов openConnection.

Более экстремальным методом была бы полная замена обработчика (возможно, расширение реализации в вашей JRE).В качестве альтернативы доступны альтернативные http-клиенты (с открытым исходным кодом).

Настройка сокета вручную работает нормально ...

private HttpsURLConnection openConnection(URL src, URL dest, SSLContext sslContext)
        throws IOException, ProtocolException {
    HttpsURLConnection connection = (HttpsURLConnection) dest.openConnection();
    HttpsHostNameVerifier httpsHostNameVerifier = new HttpsHostNameVerifier();
    connection.setHostnameVerifier(httpsHostNameVerifier);
    connection.setConnectTimeout(CONNECT_TIMEOUT);
    connection.setReadTimeout(READ_TIMEOUT);
    connection.setRequestMethod(POST_METHOD);
    connection.setRequestProperty(CONTENT_TYPE, SoapConstants.CONTENT_TYPE_HEADER);
    connection.setDoOutput(true);
    connection.setDoInput(true);
    connection.setSSLSocketFactory(sslContext.getSocketFactory());
    if ( src!=null ) {
        InetAddress inetAddress = InetAddress.getByName(src.getHost());
        int destPort = dest.getPort();
        if ( destPort <=0 ) 
            destPort=SERVER_HTTPS_PORT;
        int srcPort = src.getPort();
        if ( srcPort <=0 ) 
            srcPort=CLIENT_HTTPS_PORT;
         connectionSocket = connection.getSSLSocketFactory().createSocket(dest.getHost(), destPort, inetAddress, srcPort);
    }
    connection.connect();
    return connection;
}    
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top