简体   繁体   中英

Not getting a response when communicating with Google using java sslSocket

I am trying to write a simple web client using java's socket classes similar to telnet. I want the user to be able to communicate freely with any web server on any port. I would like to also have some built in support for HTTP/HTTPS communication. I got the HTTP part working just fine but I have been having a lot of trouble with HTTPS.

I would like to use Java's SSLSocket classes. I have looked at a lot of websites and examples and put together the following code to retrieve Google's home page.

package httpssandbox;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.cert.Certificate;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class HttpsSandbox {

    static int port = 443;
    static String addressString = "google.com";
    static InetAddress address;

    SSLSocket socket;

    PrintWriter out;
    BufferedReader in;



    public static void main(String[] args) {
        System.out.println("Connecting to: " + addressString);
        System.out.println("Using port: " + port);
        //Connect to the website
        HttpsSandbox hs = new HttpsSandbox();
        hs.connect();
    }

    public void connect(){
        try {
            //Resolve IP address
            address = InetAddress.getByName(addressString);
            System.out.println("IP address: " + address.getHostAddress());
            //Connect using a secure SSL conenction
            SSLSocketFactory socketf = HttpsURLConnection.getDefaultSSLSocketFactory();
            socket = (SSLSocket) socketf.createSocket("google.com", port);
            socket.startHandshake();
            printSocketInfo();
            //Get the input and output streams of the socket
            out = new PrintWriter(socket.getOutputStream());
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            sendHTTPGET();
            System.out.println(receive());
        } catch (UnknownHostException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private void sendHTTPGET(){
        //Construct a string with the message
        out.println("GET / HTTP/1.1");
        out.println();
        out.flush();
    }

    private String receive(){
        String message = "";
        //Wait for a message to arrive.  
        //Wouldn't want to miss any messages delayed by network connection
        try {
            while(!in.ready()) {}
            while(in.ready()){
                message += in.readLine() + "\n";
            }
            return(message);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    private void printSocketInfo(){
        System.out.println("Socket class: "+ socket.getClass());
        System.out.println("   Remote address = " + socket.getInetAddress().toString());
        System.out.println("   Remote port = " + socket.getPort());
        System.out.println("   Local socket address = " + socket.getLocalSocketAddress().toString());
        System.out.println("   Local address = " + socket.getLocalAddress().toString());
        System.out.println("   Local port = " + socket.getLocalPort());
        System.out.println("   Need client authentication = " + socket.getNeedClientAuth());
        SSLSession ss = socket.getSession();
        System.out.println("   Cipher suite = " + ss.getCipherSuite());
        System.out.println("   Protocol = " + ss.getProtocol());
        System.out.println();

        Certificate[] serverCerts = null;

        try {
            serverCerts = socket.getSession().getPeerCertificates();
        } catch (SSLPeerUnverifiedException ex) {
            ex.printStackTrace();
        }

        System.out.println("Retreived Server's Certificate Chain");

        System.out.println(serverCerts.length + "Certifcates Found\n\n\n");
        for (int i = 0; i < serverCerts.length; i++) {
            Certificate myCert = serverCerts[i];
            System.out.println("====Certificate:" + (i+1) + "====");
            System.out.println("-Public Key-\n" + myCert.getPublicKey());
            System.out.println("-Certificate Type-\n " + myCert.getType());

            System.out.println();
        }
    }
}

When I run the code, I receive the following output:

Connecting to: google.com
Using port: 443
IP address: 173.194.46.101
Socket class: class sun.security.ssl.SSLSocketImpl
   Remote address = google.com/173.194.46.101
   Remote port = 443
   Local socket address = /192.168.15.126:50357
   Local address = /192.168.15.126
   Local port = 50357
   Need client authentication = false
   Cipher suite = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
   Protocol = TLSv1

Retreived Server's Certificate Chain
3Certifcates Found



====Certificate:1====
-Public Key-
Sun EC public key, 256 bits
  public x coord: 92211319072714844469959217656780286932148107234802524635747648609523069275349
  public y coord: 36581585054743121309038603897530740476813606346857238295887416801699179162876
  parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7)
-Certificate Type-
 X.509

====Certificate:2====
-Public Key-
Sun RSA public key, 2048 bits
  modulus: 19713895149719550196537065661910573762693934593220985668782860735427060889140793885919063737778303548724916253252606564904177491762533295616984617709378739783748100146882543612565825906799282133510087546060971220666055151463898734279731009956582933624646298029265838127046200538496591314458940937082185029845612274584845875286257057247598474925565775989866310636633768255501748172403430876460228793912189332026189491067186811703150477068536877439284697584041860237489395099402658887745588613142391209024263265842301844868193180477031165936332420984796347731387363914950895491332976177715889375379088870580457661428329
  public exponent: 65537
-Certificate Type-
 X.509

====Certificate:3====
-Public Key-
Sun RSA public key, 2048 bits
  modulus: 27620593608073140957439440929253438012688864718977347268272053725994928948867769687165112265058896553974818505070806430256424431940072485024407486246475597522063246121214348496326377341879755851197260401080498544606788760407243324127929930612201002157618691487713632251700065187865963692723720912135393438861302779432180613616167225206519123176430362410262429702404863434904116727055203524505580952824336979641923534005571504410997292144760317953739063178352809680844232935574095508445145910310675421726257114605895831426222686272114090063230017292595425393719031924942422176213538487957041730136782988405751614792953
  public exponent: 65537
-Certificate Type-
 X.509

Sending message: 
GET / HTTP/1.1

Host: google.com

At this point, the code freezes up while waiting for a response from the server. This response never comes. I have tried similar code with a similar HTTP request with a different website and it has sent back a 400 error which I am not currently worried about. My goal right now is to connect with Google and get a response from the server. What I don't understand is why I'm not getting any response from the server.

Thanks for your help! I have looked all over for a solution and have been unsuccessful.

UPDATE:

I tried the code that user3586195 posted and it works great! The trick is in the receive() method. I needed to read from the stream to indicate I was ready. Thanks for everyone's help!

I don't think it is changing bufferedwriter but the following works. Trick is to read something from the connection. It never signals ready unless you read from it.

package httpssandbox;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.cert.Certificate;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class HttpsSandbox {

static int port = 443;
static String addressString = "www.google.com";
static InetAddress address;

SSLSocket socket;

PrintWriter out;
BufferedReader in;

public static void main(String[] args) {
    System.out.println("Connecting to: " + addressString);
    System.out.println("Using port: " + port);
    //Connect to the website
    HttpsSandbox hs = new HttpsSandbox();
    hs.connect();
}

public void connect() {
    try {
        //Resolve IP address
        address = InetAddress.getByName(addressString);
        System.out.println("IP address: " + address.getHostAddress());
        //Connect using a secure SSL conenction
        SSLSocketFactory socketf = HttpsURLConnection.getDefaultSSLSocketFactory();
        socket = (SSLSocket) socketf.createSocket(addressString, port);
        printSocketInfo();
        socket.setSoTimeout(10000);

        // socket.startHandshake();
        //Get the input and output streams of the socket
        out = new PrintWriter(socket.getOutputStream());
        sendHTTPGET();
        System.out.println(receive());
    } catch (UnknownHostException ex) {
        ex.printStackTrace();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

private void sendHTTPGET() {
    //Construct a string with the message
    out.println("GET / HTTP/1.1");
    out.println();
    out.flush();
    System.out.println("Sending GET / HTTP/1.1");
}

private String receive() {
    String message = "";
    //Wait for a message to arrive.  
    //Wouldn't want to miss any messages delayed by network connection
    try {
        System.out.println("Waiting for message");
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        while (!in.ready()) {
            message += in.readLine() + "\n\r";
        }
        while (in.ready()) {
             message += in.readLine() + "\n\r";
        }
        return (message);
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    return null;
}

private void printSocketInfo() {
    System.out.println("Socket class: " + socket.getClass());
    System.out.println("   Remote address = " + socket.getInetAddress().toString());
    System.out.println("   Remote port = " + socket.getPort());
    System.out.println("   Local socket address = " + socket.getLocalSocketAddress().toString());
    System.out.println("   Local address = " + socket.getLocalAddress().toString());
    System.out.println("   Local port = " + socket.getLocalPort());
    System.out.println("   Need client authentication = " + socket.getNeedClientAuth());
    SSLSession ss = socket.getSession();
    System.out.println("   Cipher suite = " + ss.getCipherSuite());
    System.out.println("   Protocol = " + ss.getProtocol());
    System.out.println();

    Certificate[] serverCerts = null;

    try {
        serverCerts = socket.getSession().getPeerCertificates();
    } catch (SSLPeerUnverifiedException ex) {
        ex.printStackTrace();
    }

    System.out.println("Retreived Server's Certificate Chain");

    System.out.println(serverCerts.length + "Certifcates Found\n\n\n");
    for (int i = 0; i < serverCerts.length; i++) {
        Certificate myCert = serverCerts[i];
        System.out.println("====Certificate:" + (i + 1) + "====");
        System.out.println("-Public Key-\n" + myCert.getPublicKey());
        System.out.println("-Certificate Type-\n " + myCert.getType());

        System.out.println();
    }
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM