您的位置:首页 > 理论基础 > 计算机网络

关于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连接。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: