关于HttpURLConnection的TCP连接
2012-09-03 19:43
405 查看
背景在工作中,我被问及一个问题CXF的WebClient是如何通过连接发送请求的,到最后引申为HttpURLConnection的TCP连接的重用问题。问题描述在一个线程中,多个方法调用HttpURLConnection conn = (HttpURLConnection) url.openConnection() 建立一次TCP连接还是多次TCP连接?具体点讲,如下代码中HttpClient有3个方法,每个都调用 HttpURLConnection conn = (HttpURLConnection) url.openConnection() ,那么一个线程调用method1, method2 然后method3, JDK会为这个线程创建多少个TCP连接?
package art.programming.net;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* see
* http://docs.oracle.com/javase/6/docs/technotes/guides/net/http-keepalive.html
*
*
* @author Alex Chen
*/
public class HttpClient {
public static void main(String... args){
try{
final URL url = new URL("http://www.google.cn");
HttpClient httpClient = new HttpClient();
httpClient.method1(url);
httpClient.method2(url);
httpClient.method3(url);
/**
new Thread(){
public void run(){
HttpClient httpClient = new HttpClient();
httpClient.method1(url);
httpClient.method2(url);
httpClient.method3(url);
}
}.start();
**/
}catch(Exception e){
}
}
public void method1(final URL url){
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("HEAD");
int len = conn.getContentLength();
System.out.println("内容长度: " + len);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void method2(final URL url){
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("HEAD");
int len = conn.getContentLength();
System.out.println("内容长度: " + len);
//conn.disconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void method3(final URL url){
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("HEAD");
int len = conn.getContentLength();
System.out.println("内容长度: " + len);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}从Wireshark抓到的数据包分析来看,答案是1个TCP连接。从上图,我观察到系统间建立连接之后(SYN,ACK)连续发送3个HTTP请求。所以即使是在不同的方法里面调用HttpURLConnection conn = (HttpURLConnection) url.openConnection() ;系统也只是创建一个连接。那么,如果是2个线程会创建多少个连接呢?我把代码修改成如下,
package art.programming.net;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* see
* http://docs.oracle.com/javase/6/docs/technotes/guides/net/http-keepalive.html
*
*
* @author Alex Chen
*/
public class HttpClient {
public static void main(String... args){
try{
final URL url = new URL("http://www.google.cn");
new Thread(){
public void run(){
HttpClient httpClient = new HttpClient();
httpClient.method1(url);
httpClient.method2(url);
httpClient.method3(url);
}
}.start();
new Thread(){
public void run(){
HttpClient httpClient = new HttpClient();
httpClient.method1(url);
httpClient.method2(url);
httpClient.method3(url);
}
}.start();
}catch(Exception e){
}
}
public void method1(final URL url){
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("HEAD");
int len = conn.getContentLength();
System.out.println("内容长度: " + len);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void method2(final URL url){
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("HEAD");
int len = conn.getContentLength();
System.out.println("内容长度: " + len);
//conn.disconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void method3(final URL url){
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("HEAD");
int len = conn.getContentLength();
System.out.println("内容长度: " + len);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}观察到2个连接被建立(两个SYN,ACK),处理6次HTTP请求。同时观察到TCP连接没有被关闭(没有FIN标志位出现)。结论URL.openConnection并不是每次都会创建一个TCP连接。
相关文章推荐
- Android4种网络连接方式HttpClient、HttpURLConnection、OKHttp和Volley优缺点
- java httpURL连接远程服务器并返回数据(httpurlconnection)
- Android4种网络连接方式HttpClient、HttpURLConnection、OKHttp和Volley优缺点和性能对比
- Android开发与服务交互过程中,HTTPURLconnection 连接失败
- Java Http连接中(HttpURLConnection)中使用代理(Proxy)及其验证(Authentication)
- Android笔记之(一)HTTP连接--HttpURLConnection方式
- Java网络连接之HttpURLConnection与HttpClient
- Java Http连接中(HttpURLConnection)中使用代理(Proxy)及其验证(Authentication)
- Android网络连接的两种方法:apache client和httpurlconnection的比较
- HttpURLConnection连接网页和获取数据的使用实例
- httpUrlConnection连接网络的用法(用到了handle传递消息,在主线程中更新UI)
- android HttpUrlConnection连接笔记
- Android网络连接之HttpURLConnection和HttpClient
- 关于HttpURLConnection测试servlet
- Android客户端连接服务器端,向服务器端发送请求HttpURLConnection
- Android网络连接之HttpURLConnection和HttpClient
- Java客户端通过HttpURLConnection连接Web服务器的Session保存问题
- 关于HttpURLConnection的一个疑问解析
- HttpUrlConnection网络连接
- 关于HttpURLConnection遇到ava.io.FileNotFoundException的解决方法