2

複数の NIC に構成されたパブリック IP アドレスのプールがあります。LINUX マシンで実行される私の Java プロジェクトでは、プールから特定の IP アドレスを選択し、その IP を使用して HttpURLConnecion を作成する必要があります。さらに、毎回異なる IP を使用して、プールを循環させます。

現段階では、java.net ライブラリを使用して解決策を見つけることができませんでした。私はむしろ、Apache の HttpClient を見てきました。次のリンクhttp://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.htmlで、そのようなライブラリは私が探していた機能をサポートできると言われています。これに関する議論は、Define source ip address using Apache HttpClientにあります。実際、投稿されたスレッドは決定的なものではないようです。ユーザーの経験は、説明されているライブラリの使用法とは非常に対照的です。

したがって、SO コミュニティがこの問題の解決に本当に成功したとは思えません。このトピックに関するいくつかのリプレイされた質問/回答がSOで見つかることは事実ですが、それらのどれも問題の徹底的な分析を提供していないようです.

さらに、(私のプロジェクトのように) java.net ライブラリを使用しても問題はまったく発生しません。

現時点で考えられるオプションは、(Java から) いくつかの LINUX システム コマンドを呼び出して、現在の接続に使用する NIC を切り替えることです。しかし、私はまだそれを理解していません。

したがって、この問題を解決する上で肯定的な経験をしたユーザーが、解決策/アイデア/方法を教えてくれれば幸いです。

前もって感謝します、

マルチェロ

アップデート:

現在、このテストコードを実装しています。正しいステータス コード (200) が表示されます。ただし、複数の IP アドレスでテストする必要があります。

public class test {

    public static void main(String[] args) {

        final String authUser = "admin";
        final String authPassword = "password";
        Authenticator.setDefault(
           new Authenticator() {
              public PasswordAuthentication getPasswordAuthentication() {
                 return new PasswordAuthentication(
                       authUser, authPassword.toCharArray());
              }
           }
        );

        System.setProperty("http.proxyUser", authUser);
        System.setProperty("http.proxyPassword", authPassword);

        try {

            Properties systemProperties = System.getProperties();
            URL url = new URL("yourURL");
            systemProperties.setProperty("http.proxyHost","localhost");
            systemProperties.setProperty("http.proxyPort", "8080");                         

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            int status = connection.getResponseCode();
            System.out.println(status);

        } catch (IOException e) {
            System.out.println("connection problems");
        }
    }

}

この時点で、各 NIC に関連するさまざまな TCP ポートを構成できるはずです。誰かがこのようなことを試しましたか?新しいアイデア/コメントを読むのを楽しみにしています。

更新 2: 正確には、必要な人のために認証設定を含めました。

4

4 に答える 4

3

org.apache.httpcomponents だけを使用しないのはなぜですか?

動作する例を次に示します (maven プラグイン org.apache.httpcomponents、バージョン 4.3.1 を使用):

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

public class HttpClientExample {

    public void gogo() throws ClientProtocolException, IOException {

        CloseableHttpClient httpclient = HttpClients.createDefault();

        // Local interface1:
        byte ip1[] = new byte[] { (byte)192, (byte)168, (byte)100, (byte)32 };
        // Local interface2:
        byte ip2[] = new byte[] { (byte)192, (byte)168, (byte)100, (byte)33 };


        RequestConfig requestConfig = RequestConfig.custom().setLocalAddress(InetAddress.getByAddress(ip1)).build();
        try {
            HttpGet httpget = new HttpGet("http://server.com");
            httpget.setConfig(requestConfig);
            System.out.println("executing request" + httpget.getRequestLine());
            StringBuilder response = httpclient.execute(httpget,handler);
            System.out.println(response.toString());

            requestConfig = RequestConfig.custom().setLocalAddress(InetAddress.getByAddress(ip2)).build();
            httpget = new HttpGet("http://server.com");
            httpget.setConfig(requestConfig);
            System.out.println("executing request" + httpget.getRequestLine());
            response = httpclient.execute(httpget,handler);
            System.out.println(response.toString());
        } finally {
            httpclient.close();
        }
    }

    private final ResponseHandler<StringBuilder> handler = new ResponseHandler<StringBuilder>() {
        @Override
        public StringBuilder handleResponse(final HttpResponse response)
                throws ClientProtocolException, IOException {
            return sortResponse(response);
        }
    };

    private StringBuilder sortResponse(final HttpResponse httpResponse) throws IOException {
        StringBuilder builder = null;

        if (httpResponse != null) {
            switch (httpResponse.getStatusLine().getStatusCode()) {
                case HttpStatus.SC_OK:
                    final HttpEntity entity = httpResponse.getEntity();
                    if (entity != null) {

                        final InputStreamReader instream = new InputStreamReader(entity.getContent());
                        try {
                            final BufferedReader reader = new BufferedReader(instream);
                            builder = new StringBuilder();
                            String currentLine = null;
                            currentLine = reader.readLine();
                            while (currentLine != null) {
                                builder.append(currentLine).append("\n");
                                currentLine = reader.readLine();
                            }
                        } finally {
                            instream.close();
                        }
                    }
                    break;
                default:
                    throw new IllegalArgumentException("Error.");
            }
        }
        return builder;
    }
}
于 2013-10-22T18:55:13.967 に答える
0

java.netsun.net.www.protocolパッケージを使用して作成しますHttpURLConnection

sun.net.www.protocol.HttpURLConnectionjava.net.HttpURLConnectionインターフェイスの実装です。

パッケージからおよびプロトコル ハンドラ クラスsun.net.www.protocol.HttpURLConnectionなどの他の適切なクラスを拡張してみてください。NetworkClientHttpClientsun.www.

于 2013-10-22T12:40:32.893 に答える
0

次のような出力を与える Linux コマンド「ip addr」を使用します。

[root@user ~]# ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
    valid_lft forever preferred_lft forever
2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:18:a5:97 brd ff:ff:ff:ff:ff:ff
    inet 100.10.52.15/24 brd 10.0.2.255 scope global eth1
    inet 100.10.52.16/24 brd 10.0.2.255 scope global secondary eth1
    inet6 fe80::a00:27ff:fe18:a597/64 scope link
       valid_lft forever preferred_lft forever
3: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:11:1f:0c brd ff:ff:ff:ff:ff:ff
    inet 158.17.47.19/24 brd 172.17.37.255 scope global eth2
    inet6 fe80::a00:27ff:fe11:1f0c/64 scope link
       valid_lft forever preferred_lft forever
4: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:cf:96:2d brd ff:ff:ff:ff:ff:ff
    inet6 fe80::a00:27ff:fecf:962d/64 scope link
       valid_lft forever preferred_lft forever
  1. デフォルトでは、Linux は最初の IP アドレスを特定のアダプタのソース IP アドレスとして使用します。たとえば、上記のシステム構成では、Linux はソース IP アドレスとして「100.10.52.15/24」を使用します。

  2. 「ProcessBuilder」でJavaプログラムを作成し、次のコマンドを実行してIPアドレスの順序を変更できます。(コマンド: ip addr del 100.10.25.15/24 dev eth0

    ip addr add 100.10.25.15/24 dev eth0)

  3. 特定のアダプタのすべての IP アドレスを削除し、メモリに保存します。必要な順序で追加します (ソース IP として使用する IP アドレスを最初に追加する必要があります)

  4. たとえば、IP アドレス「100.10.52.16/24」を送信元 IP アドレスとして使用する必要があります。

    ip addr del 100.10.25.15/24 dev eth0
    ip addr del 100.10.25.16/24 dev eth0
    
    ip addr add 100.10.25.16/24 dev eth0
    ip addr add 100.10.25.15/24 dev eth0
    
于 2013-10-22T13:40:19.070 に答える
-1

まあ、私は同じことについてその特定の答えを持っていませんが、これを試すことができますが、それがうまくいくかどうかはわかりませんが、一度試してみてください.

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);
于 2013-10-22T11:44:08.753 に答える