天天看點

關于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

<code>package</code> <code>test;</code>

<code>                                        </code> 

<code>import</code> <code>java.io.ioexception;</code>

<code>import</code> <code>org.apache.commons.httpclient.httpclient;</code>

<code>import</code> <code>org.apache.commons.httpclient.httpexception;</code>

<code>import</code> <code>org.apache.commons.httpclient.simplehttpconnectionmanager;</code>

<code>import</code> <code>org.apache.commons.httpclient.methods.getmethod;</code>

<code>import</code> <code>org.junit.test;</code>

<code>/**</code>

<code> </code> <code>* todo comment of testhttpclient</code>

<code> </code> <code>*</code>

<code> </code> <code>*  yihua.huang</code>

<code> </code> <code>*/</code>

<code>public</code> <code>class</code> <code>testhttpclient {</code>

<code>    </code> <code></code>

<code>    </code> <code>public</code> <code>void</code> <code>testheader() {</code>

<code>        </code> <code>httpclient httpclient = </code><code>new</code> <code>httpclient(</code> <code>new</code> <code>simplehttpconnectionmanager(</code> <code>true</code> <code>));</code>

<code>        </code> <code>httpclient.gethttpconnectionmanager().getparams().setsotimeout(</code> <code>5000</code> <code>);</code>

<code>        </code> <code>httpclient.gethttpconnectionmanager().getparams().setconnectiontimeout(</code> <code>5000</code> <code>);</code>

<code>        </code> <code>getmethod get = </code><code>new</code> <code>getmethod(</code> <code>""</code> <code>);</code>

<code>        </code> <code>try</code> <code>{</code>

<code>            </code> <code>httpclient.executemethod(get);</code>

<code>        </code> <code>} </code><code>catch</code> <code>(httpexception e) {</code>

<code>            </code> <code>// todo auto-generated catch block</code>

<code>            </code> <code>e.printstacktrace();</code>

<code>        </code> <code>} </code><code>catch</code> <code>(ioexception e) {</code>

<code>        </code> <code>}</code>

<code>            </code> <code>thread.sleep(</code> <code>10000</code> <code>);</code>

<code>        </code> <code>} </code><code>catch</code> <code>(interruptedexception e1) {</code>

<code>            </code> <code>e1.printstacktrace();</code>

<code>        </code> <code>get = </code><code>new</code> <code>getmethod(</code> <code>""</code> <code>);</code>

<code>        </code> <code>get.setrequestheader(</code> <code>"connection"</code> <code>, </code><code>"keep-alive"</code> <code>);</code>

<code>    </code> <code>}</code>

<code>}</code>

   請求結果如下。可以看到,圖一中共有兩次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無效

   總結:

keep-alive隻是http1.0時代對持久化連接配接的叫法,目前http1.1已經預設所有請求都是持久化的,rfc規範是正确的。

頭部不設定connection: keep-alive,依然會進行持久化連接配接。

如果設定connection:close,則不進行持久化連接配接。

目前連接配接過期時間在服務端設定,keep-alive頭設定逾時時間的做法已經不再有效。