How do you debug a hanging socket connection?
We are connecting to a web service as follows:
URL url = new URL("https://...");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POS开发者_StackOverflow中文版T");
conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-length", "" + data.length());
conn.setDoOutput(true);
OutputStreamWriter o = new OutputStreamWriter(conn.getOutputStream());
Sometimes, the connection hangs on this last line, with either a very long or infinite timeout.
How can we get into this and find out what is happening, for sure? (We have plenty of speculation, but little confirmation at this point.) We've instrumented our code with plenty of logging statements (which is how we know where the stopping point is), but can't very well do the same for Java libraries. What additional information can we convince these classes to tell us? If we wanted to set a timeout, how would we do it?
How do we debug this?
If you are using Sun's JSSE provider to support SSL (which is the default behavior when using an "https:" URL in a Sun runtime), you can set the javax.net.debug
system property to view progress of the SSL handshake.
Details about the values that can be used are in the JSSE reference guide; to turn on all SSL debugging, use something like
java -Djavax.net.debug=all com.y.MyClass
Since most of the initial handshake is unencrypted, a tool like Wireshark can be pretty useful too, if you are familiar with SSL. If you have the server private key, Wireshark is supposed to be able to decrypt a conversation too (as long as you aren't using an ephemeral cipher suite), but I've never been able to get it to work.
You might be getting stuck because of a Keep-Alive connection. Try forcing the connection to close...
URL url = new URL("https://...");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "close");
conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-length", "" + data.length());
conn.setDoOutput(true);
OutputStreamWriter o = new OutputStreamWriter(conn.getOutputStream());
精彩评论