http 長連接,短連接(轉載)

chyx413332087 13年前發布 | 5K 次閱讀

HTTP是無狀態的
也就是說,瀏覽器和服務器每進行一次HTTP操作,就建立一次連接,但任務結束就中斷連接。如果客戶端瀏覽器訪問的某個HTML或其他類型的Web頁中包含有其他的Web資源,如JavaScript文件、圖像文件、CSS文件等;當瀏覽器每遇到這樣一個Web資源,就會建立一個HTTP會話

HTTP1.1和HTTP1.0相比較而言,最大的區別就是增加了持久連接支持(貌似最新的 http1.0 可以顯示的指定 keep-alive),但還是無狀態的,或者說是不可以信任的。

如果瀏覽器或者服務器在其頭信息加入了這行代碼

Connection:keep-alive

TCP連接在發送后將仍然保持打開狀態,于是,瀏覽器可以繼續通過相同的連接發送請求。保持連接節省了為每個請求建立新連接所需的時間,還節約了帶寬。

實現長連接要客戶端和服務端都支持長連接。

如果web服務器端看到這里的值為“Keep-Alive”,或者看到請求使用的是HTTP 1.1HTTP 1.1默認進行持久連接),它就可以利用持久連接的優點,當頁面包含多個元素時(例如Applet,圖片),顯著地減少下載所需要的時間。要實現這一點, web服務器需要在返回給客戶端HTTP頭信息中發送一個Content-Length(返回信息正文的長度)頭,最簡單的實現方法是:先把內容寫入ByteArrayOutputStream,然 后在正式寫出內容之前計算它的大小

無論客戶端瀏覽器 (Internet Explorer) 還是 Web 服務器具有較低的 KeepAlive 值,它都將是限制因素。例如,如果客戶端的超時值是兩分鐘,而 Web 服務器的超時值是一分鐘,則最大超時值是一分鐘。客戶端或服務器都可以是限制因素

在header中加入 --Connection:keep-alive
在HTTp協議請求和響應中加入這條就能維持長連接。
再封裝HTTP消息數據體的消息應用就顯的非常簡單易用

Http Keep-Alive seems to be massively misunderstood. Here's a short description of how it works, under both 1.0 and 1.1

HTTP/1.0

Under HTTP 1.0, there is no official specification for how keepalive operates. It was, in essence, tacked on to an existing protocol. If the browser supports keep-alive, it adds an additional header to the request:

Connection: Keep-Alive

Then, when the server receives this request and generates a response, it also adds a header to the response:

Connection: Keep-Alive

Following this, the connection is NOT dropped, but is instead kept open. When the client sends another request, it uses the same connection. This will continue until either the client or the server decides that the conversation is over, and one of them drops the connection.

HTTP/1.1

Under HTTP 1.1, the official keepalive method is different. All connections are kept alive, unless stated otherwise with the following header:

Connection: close

The Connection: Keep-Alive header no longer has any meaning because of this.

Additionally, an optional Keep-Alive: header is described, but is so underspecified as to be meaningless. Avoid it.

Not reliable

HTTP is a stateless protocol - this means that every request is independent of every other. Keep alive doesn’t change that. Additionally, there is no guarantee that the client or the server will keep the connection open. Even in 1.1, all that is promised is that you will probably get a notice that the connection is being closed. So keepalive is something you should not write your application to rely upon.

KeepAlive and POST

The HTTP 1.1 spec states that following the body of a POST, there are to be no additional characters. It also states that "certain" browsers may not follow this spec, putting a CRLF after the body of the POST. Mmm-hmm. As near as I can tell, most browsers follow a POSTed body with a CRLF. There are two ways of dealing with this: Disallow keepalive in the context of a POST request, or ignore CRLF on a line by itself. Most servers deal with this in the latter way, but there's no way to know how a server will handle it without testing.

Java應用

client用apache的commons-httpclient來執行method 。
用 method.setRequestHeader("Connection" , "Keep-Alive" or "close") 來控制是否保持連接。

常用的apache、resin、tomcat等都有相關的配置是否支持keep-alive。

tomcat中可以設置:maxKeepAliveRequests

The maximum number of HTTP requests which can be pipelined until the connection is closed by the server. Setting this attribute to 1 will disable HTTP/1.0 keep-alive, as well as HTTP/1.1 keep-alive and pipelining. Setting this to -1 will allow an unlimited amount of pipelined or keep-alive HTTP requests. If not specified, this attribute is set to 100.



解釋1

所謂長連接指建立SOCKET連接后不管是否使用都保持連接,但安全性較差,  
所謂短連接指建立SOCKET連接后發送后接收完數據后馬上斷開連接,一般銀行都使用短連接

解釋2

長連接就是指在基于tcp的通訊中,一直保持連接,不管當前是否發送或者接收數據。  
而短連接就是只有在有數據傳輸的時候才進行連接,客戶-服務器通信/傳輸數據完畢就關閉連接。

解釋3

長連接和短連接這個概念好像只有移動的CMPP協議中提到了,其他的地方沒有看到過。  
通信方式  
各網元之間共有兩種連接方式:長連接和短連接。所謂長連接,指在一個TCP連接上可以連續發送多個數據包,在TCP連接保持期間,如果沒有數據包發送,需要雙方發檢測包以維持此連接。短連接是指通信雙方有數據交互時,就建立一個TCP連接,數據發送完成后,則斷開此TCP連接,即每次TCP連接只完成一對 CMPP消息的發送。  
現階段,要求ISMG之間必須采用長連接的通信方式,建議SP與ISMG之間采用長連接的通信方式。

解釋4

短連接:比如http的,只是連接、請求、關閉,過程時間較短,服務器若是一段時間內沒有收到請求即可關閉連接。  
長連接:有些服務需要長時間連接到服務器,比如CMPP,一般需要自己做在線維持。



最近在看“服務器推送技術”,在B/S結構中,通過某種magic使得客戶端不需要通過輪詢即可以得到服務端的最新信息(比如股票價格),這樣可以節省大量的帶寬。
     傳統的輪詢技術對服務器的壓力很大,并且造成帶寬的極大浪費。如果改用ajax輪詢,可以降低帶寬的負荷(因為服務器返回的不是完整頁面),但是對服務器的壓力并不會有明顯的減少。
    而推技術(push)可以改善這種情況。但因為HTTP連接的特性(短暫,必須由客戶端發起),使得推技術的實現比較困難,常見的做法是通過延長http連接的壽命,來實現push。
    接下來自然該討論如何延長http連接的壽命,最簡單的自然是死循環法:
    【servlet代碼片段】
     public void doGet(Request req, Response res) {
          PrintWriter out = res.getWriter();
          ……
          正常輸出頁面
          ……
          out.flush();
          while (true) {
                out.print("輸出更新的內容");
                out.flush();
                Thread.sleep(3000);
          }
      }
     如果使用觀察者模式則可以進一步提高性能。
     但是這種做法的缺點在于客戶端請求了這個servlet后,web服務器會開啟一個線程執行servlet的代碼,而servlet由遲遲不肯結束,造成該線程也無法被釋放。于是乎,一個客戶端一個線程,當客戶端數量增加時,服務器依然會承受很大的負擔。
     要從根本上改變這個現象比較復雜,目前的趨勢是從web服務器內部入手,用nio(JDK 1.4提出的java.nio包)改寫request/response的實現,再利用線程池增強服務器的資源利用率,從而解決這個問題,目前支持這一非J2EE官方技術的服務器有GlassfishJetty(后者只是聽說,沒有用過)。
     目前也有一些框架/工具可以幫助你實現推功能,比如pushlets。不過沒有深入研究。
 本文由用戶 chyx413332087 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!