2011-08-29 69 views
12

ソケットサーバーに接続するコードがあり、正常に動作します。HTTPプロキシ経由でソケットサーバーを接続する方法

Socket socket = new Socket(); 
socket.connect(new InetSocketAddress(address, port)); 

ここでHTTPプロキシ経由で接続したいのですが、どうすればよいですか?

は、私はこれを試してみました

SocketAddress proxyAddr = new InetSocketAddress(proxyHost, proxyPort); 
Proxy proxy = new Proxy(Proxy.Type.SOCKS, addr); 
Socket socket = new Socket(proxy); 
socket.connect(new InetSocketAddress(address, port)); 

this postは私がJakarta CommonsのHttpClientをを使用する必要がありますが、どのようにHTTPプロキシを経由してソケットサーバーを接続するためにそれを使用することを示唆しませんでしたか?

更新日: 私はHTTPプロキシを使用する場合、私はSOCKSプロキシを使用し、それが動作しません:

SocketAddress proxyAddr = new InetSocketAddress(proxyHost, proxyPort); 
Proxy proxy = new Proxy(Proxy.Type.HTTP, addr); 
Socket socket = new Socket(proxy); 
socket.connect(new InetSocketAddress(address, port)); 

をし、それはあなたが要求しているようにはIllegalArgumentException

java.lang.IllegalArgumentException: Proxy is null or invalid type 
    at java.net.Socket.<init>(Socket.java:88) 
+0

いくつかの良い情報を持っています。http://ダウンロード.oracle.com/javase/6/docs/technotes/guides/net/proxies.html –

+0

sun.net.www.protocol.http.HttpURLConnectionにdoTunneling()があります。おそらく、そのクラスを選び、トンネルが確立された後でソケットの下にアクセスすることは可能かもしれませんが、いつでも離れる可能性のある適切なAPIを使用しています。これは、HttpClientを使用した場合には問題にはなりません。 – prunge

+0

あなたはこれを理解することができますか?私が今見ている問題です。 – user2202911

答えて

0

が見えるスローされますがSOCKSプロキシ.HTTPプロキシとは異なります。おそらくProxy.Type.HTTPを試してみてください。

質問:お客様のクライアントはHTTPベースですか?クライアントがHTTPを話さない限り、これが機能するかどうかはわかりません。

+0

ヒントのおかげで、私はHTTPを試しても、うまくいきません。私のクライアントはHTTPベースであり、このHTTPプロキシを使用してHTTPサーバーに接続すると正常に動作します – Johnny

2

トンネルの両側で動作するソフトウェアが必要ですが、JHttpTunnelを試してみることもできます。

+0

問題はどちらの側にもソフトウェアをインストールできないことです。私はJHttpTunnelを見ましたが、ApacheやAndroidには同じ方法がありますか? – Johnny

+0

@Johnny両側にソフトウェアをインストールできない場合は、JHttpTunnelは機能しません。 JHttpTunnelは、[GNU HttpTunnel](http://www.nocrew.org/software/httptunnel.html)に基づいています。 – prunge

1

HTTP tunnelingのWikipediaによると、HTTPプロキシについて重要なことは、HTTPプロトコルをプロキシすることです。

サーバーとクライアントがあり、HTTPプロキシ経由で通信したい場合は、サーバーとクライアントの両方を変更してHTTPプロトコルを伝達する必要があります。

また、OpenVPNなどVPN over HTTPを実装できる追加のソフトウェアが必要です。

編集:例外は、いくつかのHTTPプロキシサーバのサポートとは、HTTP経由での基本的なセットアッププロセスの後、通常のTCPソケットの作成とルーティングを可能HTTP CONNECTというメソッドを有効にしているということです。これにより、HTTPトンネリングに完全に変換することなく、アプリケーションへの接続が可能になります。これの良い例はMSN Messengerです。しかし、Wikipediaの記事では、セキュリティ上の理由から、この機能はしばしば無効にされています。

SocketAddress addr = new InetSocketAddress("webcache.mydomain.com", 8080); 
Proxy proxy = new Proxy(Proxy.Type.HTTP, addr); 

は、この新しいプロキシオブジェクトはプロキシ定義、何よりもを表し、覚えておいてください:

+0

プログラムでこれを行うのに役立つライブラリがありますか? – Johnny

+0

@ Johnny主な要件は、変更可能なターゲットホストの横にサーバーを置くことです。 –

+1

実際のところ、HTTP CONNECTメソッドを使用してストリームをトンネリングすることはできます。 –

2

これは私が以前に掲載のリンクからです。どのようにこのようなオブジェクトを使用するのですか?新しいopenConnection()メソッドがURLクラスに追加され、Proxyを引数として取ります。これは引数なしでopenConnection()と同じ方法で動作しますが、指定されたプロキシを介して接続が確立され、その他の設定はすべて無視されます。上記のシステム特性。

だから、前の例を完了し、我々は今、追加することができます。これは私が以前の投稿のリンクからである

URL url = new URL("http://java.sun.com/"); 
URLConnection conn = url.openConnection(proxy); 

を。私はiPad上にあるので、正しくフォーマットすることはできません。

このようにできますか?私はあなたが直接ソケットをやっているのを見ていますが、httpをやっているので多分このようにしていますか?

+0

ありがとうございます。私はURLConnectionで正常に動作していますが、問題はホストサーバーがソケット接続のみを受け付け、プロキシサーバーはHTTP接続のみを受け入れることです。だから私はHTTPプロキシ経由でソケットサーバーに接続する必要があります。 – Johnny

0

私はあなたが望むものがHTTPサーバ(http rfc 2616から)へのCONNECTメソッドを確立するためにHTTPプロキシを使用することを訂正していますか?基本的には、接続は次のようになります:

 -open a socket to the proxy (host, port) 
    -send text to the proxy with basic header 
    ....CONNECT remote.internethost.com:1494 HTTP/1.0 
    ....User-Agent: Java Proxy Socket version 1.0a 
    ....Host: remote.internethost.com 
    ....Proxy-Authorization: Basic YourBase64usernamePasswordIfRequired 
    -then, the proxy will return a http status code (multiline text string) and the actual socket (if successfull) 
    -this is this socket that needs to be returned to the connection object 

これは個人的なクラスではできますが、それはプロキシクラスを再利用することです。このようにして、httpプロキシ、特にレスポンスコードでのハンドシェイクがすべて処理されます。

0

さて、あなたは次のようにJavaのURLを右プロキシのURLの後に要求されたURLを設定、または使用してプロキシを管理することができます:あなたはhttp://ProxyHost:ProxyPorthttp://destinationAddressのようなURLを構築し、これを使用することにより

URL u = new URL("http", ProxyHost, ProxyPort, destinationAddress); 

ので、あなたはしないでくださいあなたは常にデフォルトとしてオーセンティケータを設定することができ、認証の設定を管理する必要がある場合は

java.lang.IllegalArgumentException: Proxy is null or invalid type 
    at java.net.Socket.<init>(Socket.java:88) 

:そう述べた例外がスローされますJavaでプロキシクラスのインスタンスを設定する必要があります。それはそれはあなたが設定する必要があり、プロキシのようなものだならば、それはHTTPプロキシタイプのために働く可能性が非常に高いのプロキシを設定するには、非常に「ルディメンタル」の方法だにもかかわらず

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

2

ソケットを介してHTTP CONNECTを処理するための小さなソケットファクトリクラスを作成しました。プロキシが宛先へのCONNECTをサポートしている場合、ソケットは通常通りに使用できます。

プロキシ経由ソックスを使用して、Cと
public final class SocketFactory { 

    public static Socket GetSocket(String host, String port) throws IOException { 

     /************************* 
     * Get the jvm arguments 
     *************************/ 

     int proxyPort = Integer.parseInt(System.getProperty("http.proxyPort")); 
     String proxyHost = System.getProperty("http.proxyHost"); 

     // Socket object connecting to proxy 
     Socket sock = new Socket(proxyHost, proxyPort); 

     /*********************************** 
     * HTTP CONNECT protocol RFC 2616 
     ***********************************/ 
     String proxyConnect = "CONNECT " + host + ":" + port; 

     // Add Proxy Authorization if proxyUser and proxyPass is set 
     try { 
      String proxyUserPass = String.format("%s:%s", 
        System.getProperty("http.proxyUser"), 
        System.getProperty("http.proxyPass")); 

      proxyConnect.concat(" HTTP/1.0\nProxy-Authorization:Basic " 
        + Base64.encode(proxyUserPass.getBytes())); 
     } catch (Exception e) { 
     } finally { 
      proxyConnect.concat("\n\n"); 
     } 

     sock.getOutputStream().write(proxyConnect.getBytes()); 
     /***********************************/ 

     /*************************** 
     * validate HTTP response. 
     ***************************/ 
     byte[] tmpBuffer = new byte[512]; 
     InputStream socketInput = sock.getInputStream(); 

     int len = socketInput.read(tmpBuffer, 0, tmpBuffer.length); 

     if (len == 0) { 
      throw new SocketException("Invalid response from proxy"); 
     } 

     String proxyResponse = new String(tmpBuffer, 0, len, "UTF-8"); 

     // Expecting HTTP/1.x 200 OK 
     if (proxyResponse.indexOf("200") != -1) { 

      // Flush any outstanding message in buffer 
      if (socketInput.available() > 0) 
       socketInput.skip(socketInput.available()); 

      // Proxy Connect Successful, return the socket for IO 
      return sock; 
     } else { 
      throw new SocketFactoryException("Fail to create Socket", 
        proxyResponse); 
     } 
    } 

    /** 
    * Simplest Base64 Encoder adopted from GeorgeK 
    * 
    * @see http://stackoverflow.com/questions/469695/decode-base64-data-in-java/4265472#4265472 
    */ 
    private static class Base64 { 
     /*********************** 
     * Base64 character set 
     ***********************/ 
     private final static char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/" 
       .toCharArray(); 

     /** 
     * Translates the specified byte array into Base64 string. 
     * 
     * @param buf 
     *   the byte array (not null) 
     * @return the translated Base64 string (not null) 
     */ 
     public static String encode(byte[] buf) { 
      int size = buf.length; 
      char[] ar = new char[((size + 2)/3) * 4]; 
      int a = 0; 
      int i = 0; 
      while (i < size) { 
       byte b0 = buf[i++]; 
       byte b1 = (i < size) ? buf[i++] : 0; 
       byte b2 = (i < size) ? buf[i++] : 0; 

       int mask = 0x3F; 
       ar[a++] = ALPHABET[(b0 >> 2) & mask]; 
       ar[a++] = ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask]; 
       ar[a++] = ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask]; 
       ar[a++] = ALPHABET[b2 & mask]; 
      } 
      switch (size % 3) { 
      case 1: 
       ar[--a] = '='; 
      case 2: 
       ar[--a] = '='; 
      } 
      return new String(ar); 
     } 
    } 
} 

https://code.google.com/p/java-socket-over-http-proxy-connect/

-1

I`m coddingアプリ++、このツールは私をたくさん助けて、ここにも見HERE

+1

いくつかのコード例を過去にしてください – BillyBigPotatoes

+0

私が提供するLinkは、デモのオープンソースです。 –

関連する問題