• 关于HTTP keep-alive的实验(转至 http://my.oschina.net/flashsword/blog/80037)


    前面一篇文章提到,HTTP1.1中持久连接已经是默认配置,除非设置Connection为close,否则默认都会进行持久连接。但是我们知道事实标准跟教科书还是可能会有一定差距的,所以不妨自己尝试一下。

       我们知道,TCP建立连接时会进行三次握手,而握手是以一方发送一个SYN为开始的。下载抓包工具Wireshark之后,进行抓包调试。在Java里实现了一段模拟请求的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    package test;
                                             
    import java.io.IOException;
                                             
    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.HttpException;
    import org.apache.commons.httpclient.SimpleHttpConnectionManager;
    import org.apache.commons.httpclient.methods.GetMethod;
    import org.junit.Test;
                                             
    /**
      * TODO Comment of TestHttpClient
      *
      @author yihua.huang
      *
      */
    public class TestHttpClient {
                                             
         @Test
         public void testHeader() {
             HttpClient httpClient = new HttpClient( new SimpleHttpConnectionManager( true ));
             httpClient.getHttpConnectionManager().getParams().setSoTimeout( 5000 );
             httpClient.getHttpConnectionManager().getParams().setConnectionTimeout( 5000 );
             GetMethod get = new GetMethod( "http://www.dianping.com" );
             try {
                 httpClient.executeMethod(get);
             catch (HttpException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             catch (IOException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
             try {
                 Thread.sleep( 10000 );
             catch (InterruptedException e1) {
                 // TODO Auto-generated catch block
                 e1.printStackTrace();
             }
             get = new GetMethod( "http://www.dianping.com" );
             get.setRequestHeader( "Connection" "keep-alive" );
             try {
                 httpClient.executeMethod(get);
             catch (HttpException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             catch (IOException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
         }
                                             
    }

       请求结果如下。可以看到,图一中共有两次HTTP请求,但是只建立了一次TCP连接,说明持久连接是有效的。而等到10秒之后(代码40行开始)的HTTP请求,又会重新建立连接,证明keep-alive已经过了超时时间。然后在头中加入Keep-Alive: 300,结果第二次请求仍然会重新连接,证明服务器端对于Keep-alive超时进行了配置,并不接受Keep-Alive: 300头。

       

     

    图1 第一次请求,keep-alive生效

    图2 10秒后第二次请求,keep-alive过期

       然后我们将Connection头设置为close,重试。发现确实建立了两次TCP连接。

    图3 设置Connection:close后,keep-alive无效

       总结:

    1. Keep-alive只是HTTP1.0时代对持久化连接的叫法,目前HTTP1.1已经默认所有请求都是持久化的,RFC规范是正确的。

    2. 头部不设置Connection: keep-alive,依然会进行持久化连接。

    3. 如果设置Connection:close,则不进行持久化连接。

    4. 目前连接过期时间在服务端设置,Keep-Alive头设置超时时间的做法已经不再有效。

  • 相关阅读:
    WPF 进度条
    WPF CPU使用率线性表
    Android annotation
    git 操作
    git 合并指定目录到master
    远程连接mysql报错,ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: NO)解决方案
    centos7 安装python2.7.14 并与原版本共存
    pycahrm 断点调试
    ImportError: No module named Crypto.Cipher 报错解决方法
    python操作 rabbitMQ
  • 原文地址:https://www.cnblogs.com/kobe8/p/3702071.html
Copyright © 2020-2023  润新知