怎麼理解TCP是面向連接的,HTTP基於TCP卻是無連接的?
怎麼理解TCP是面向連接的,HTTP基於TCP卻是無連接的?
使用應用層協議HTTP進行網路請求時,調用下層的TCP,雖然應用層HTTP只有一次請求,但傳輸層卻進行了TCP的三次握手。如果使用socket編程,就是直接使用傳輸層TCP,放棄使用傳輸層以上的協議,也就是如果同一連接使用socket就不能同時使用HTTP。
這樣理解對嗎?
現實生活中最能模擬TCP/HTTP關係的就是:電話/人,先連接,後通信的模式。
先來看看羅密歐與朱麗葉怎麼打電話的
第一步:羅密歐撥號碼 5201314,馬上就能通話嗎?不能!因為還沒有連接,電話機把號碼傳給電信局交換機,中間經過若干交換機,最終到達朱麗葉電話機,電話鈴響
第二步:這時能通話嗎?不能,因為連接還沒有完成!在朱麗葉拿起話機的那一刻,電話機發送off-hook(摘機)消息給電信局交換機,意思是接收電話連接,這個消息原路返回,到達羅密歐話機,羅密歐的話機接收到這個確認消息,電話連接完畢。
第三步:羅密歐激動地說:約嗎?
第四步:朱麗葉故作漫不經心地說:約!
第五步:羅密歐強壓內心驚喜:不見不散。
第六步:朱麗葉:好!然後掛機。
第七步:朱麗葉話機發on-hook (掛機)消息給交換機,一級級傳達這個release消息到羅密歐話機
第八步:羅密歐端的交換機發release confirm 消息予以確認,消息途徑的所有交換機釋放circuit,至此,電話完全關閉。
再來看看基於TCP的HTTP網頁版聊天畫面:
第一步:羅密歐輸入朱麗葉的IP= 52.0.13.14,這時能聊天嗎?不能!因為還需要TCP連接,發TCP SYN消息
第二步:這時能聊天嗎?不能,TCP還沒有接通,朱麗葉的TCP發SYN + ACK,接受TCP連接
第三步:羅密歐迫不及待地輸入文字:約嗎?(TCP 連接完成)
第四步:朱麗葉電腦彈出一個消息框,然後朱麗葉故作不經意地回復:約!
第五步:羅密歐竊喜:不見不散。
第六步:朱麗葉:好!關閉對話框。
第七步:朱麗葉瀏覽器發close消息給TCP,TCP發FIN消息給對方,一跳一跳的方式到達羅密歐的TCP
第八步:羅密歐的TCP 發 FIN + ACK消息予以確認
第九步:朱麗葉的TCP發ACK最後確認,雙向連接全部關閉。
仔細對照一下,兩種通信方式大同小異,問HTTP是不是連接,就好比問羅密歐與朱麗葉是不是連接的?事實上,羅密歐朱麗葉只是藉助底層的電話連接來交換信息而已,他們無需連接;HTTP也是一樣,藉助底層的TCP虛擬連接,採用的QA的方式對話,無需連接。
無論是電話連接,還是TCP連接,都是虛擬連接,只有水管這樣看得見摸的著的才算物理連接。如果一個會話需要多個層級的連接,會造成延遲大、資源浪費,所以如果一個層級已經提供了可靠連接,則其它層級完全沒有必要連接,只需要交流信息即可,比如這裡的HTTP。
Socket 提供的是訪問二三四層的介面,如果訪問的是TCP的介面(四層介面Socket),則自己要實現HTTP協議的細節,然後把HTTP打包好的數據發給TCP介面即可。
HTTP是無連接的是什麼鬼說法,應該是短連接吧?然而實際上「HTTP=短連接」早就已經是過去式了
HTTP連接方式的進化史:
HTTP/0.9時代:短連接
每個HTTP請求都要經歷一次DNS解析、三次握手、傳輸和四次揮手。反覆創建和斷開TCP連接的開銷巨大,在現在看來,這種傳輸方式簡直是糟糕透頂。
HTTP/1.0時代:持久連接概念提出
人們認識到短連接的弊端,提出了持久連接的概念,在HTTP/1.0中得到了初步的支持。
持久連接,即一個TCP連接服務多次請求:
客戶端在請求header中攜帶Connection:
Keep-Alive,即是在向服務端請求持久連接。如果服務端接受持久連接,則會在響應header中同樣攜帶Connection:
Keep-Alive,這樣客戶端便會繼續使用同一個TCP連接發送接下來的若干請求。(Keep-Alive的默認參數是[timout=5,
max=100],即一個TCP連接可以服務至多5秒內的100次請求)
當服務端主動切斷一個持久連接時(或服務端不支持持久連接),則會在header中攜帶Connection: Close,要求客戶端停止使用這一連接。
HTTP/1.1時代:持久連接成為默認的連接方式;提出pipelining概念
HTTP/1.1開始,即使請求header中沒有攜帶Connection: Keep-Alive,傳輸也會默認以持久連接的方式進行。
目前所有的瀏覽器都默認請求持久連接,幾乎所有的HTTP服務端也都默認開啟對持久連接的支持,短連接正式成為過去式。(HTTP/1.1的發布時間是1997年,最後一次對協議的補充是在1999年,我們可以誇張地說:HTTP短連接這個概念已經過時了近20年了。)
同時,持久連接的弊端被提出 —— HOLB(Head of Line Blocking)
即持久連接下一個連接中的請求仍然是串列的,如果某個請求出現網路阻塞等問題,會導致同一條連接上的後續請求被阻塞。
所以HTTP/1.1中提出了pipelining概念,即客戶端可以在一個請求發送完成後不等待響應便直接發起第二個請求,服務端在返迴響應時會按請求到達的順序依次返回,這樣就極大地降低了延遲。
然而pipelining並沒有徹底解決HOLB,為了讓同一個連接中的多個響應能夠和多個請求匹配上,響應仍然是按請求的順序串列返回的。所以pipelining並沒有被廣泛接受,幾乎所有代理服務都不支持pipelining,部分瀏覽器不支持pipelining,支持的大部分也會將其默認關閉。
SPDY和HTTP/2:multiplexing
multiplexing即多路復用,在SPDY中提出,同時也在HTTP/2中實現。
multiplexing技術能夠讓多個請求和響應的傳輸完全混雜在一起進行,通過streamId來互相區別。這徹底解決了holb問題,同時還允許給每個請求設置優先順序,服務端會先響應優先順序高的請求。
現在Chrome、FireFox、Opera、IE、Safari的最新版本都支持SPDY,Nginx/Apache HTTPD/Jetty/Tomcat等服務端也都提供了對SPDY的支持。
另外,谷歌已經關閉SPDY項目,正式為HTTP/2讓路。可以認為SPDY是HTTP/2的前身和探路者。
HTTP使用TCP的目的難道不是為了保證HTTP數據傳輸的可靠性?
例如是使用瀏覽器瀏覽百度搜索的主頁
第一步:你發出HTTP請求 (在地址欄輸入http://www.baidu.com/,然後敲回車)
第二步:百度伺服器收到你的HTTP請求
第三步:百度伺服器把 http://www.baidu.com/ 這個默認主頁返回到你的電腦
第四步:你的瀏覽器上顯示出 百度搜索 的主頁
使用TCP的目的是保證你所發送的請求和百度伺服器返回的頁面這兩者信息傳輸的完整性。
有些頁面包含的文字、圖片很多,伺服器需要把整個頁面分割成許多個數據包再發到你的電腦上,如果中途因為網路擁擠等原因,丟失了部分數據包,那你在電腦上顯示的請求頁面是不完整的。
例如,如果百度的伺服器返回給你的主頁數據在傳輸過程中丟失了一部分,剛好丟失的部分是
包含這個圖片的數據包。
那你在電腦上看到的百度主頁可能是這樣的:
所以,HTTP使用TCP的目的是為了保證數據傳輸的可靠性和完整性。
TCP的面向連接是基於網路底層的數據傳輸。
HTTP的無連接是基於應用層面的溝通交互。
HTTP1.1 HTTP2 其實是有連接,有狀態的。看你怎麼玩。
就是你為你老闆工作 你是想著怎麼漲工資
你老闆呢?在你們的工作之上 他思考著如何改變世界
所以說 每一個東西都有自己要承載的東西 TCP關注連接 HTTP關注服務
不是說我關注一個東西 我就沒有另外一個東西 這是不合邏輯的~
不知道你說的HTTP的無連接指的是什麼,姑且認為你說的是無狀態。
HTTP無狀態指的是上一次會話和下一次會話沒有關聯,因為每一次HTTP請求都是一個新的鏈接,就算是同一個用戶發起的兩次HTTP請求,如果你不用額外的手段(比如每次都把用戶的標識傳過來),你是不知道這兩次請求是不是同一個用戶發來的。
而TCP協議是長連接的,同一個用戶建立起一條tcp連接後,發送和接受消息都是走同一條鏈路,你可以確定這些消息是來自哪個鏈路的(就可以確定用戶是誰)
事實上HTTP協議和TCP協議是處於不同層次的,TCP協議處於更底層,用來實現可靠的網路傳輸,他並不關注傳輸的內容是什麼。
而HTTP協議是為了萬維網設計的,是為了實現在web伺服器和瀏覽器之間傳輸超文本內容的,它不關注這些內容是怎麼傳輸的,它只要求這些內容能被可靠傳輸,協議所關注的是這些通過網路傳輸過來的數據,正確的解析這些傳輸的數據,保證瀏覽器和web伺服器可以正常的「溝通」,這才是HTTP協議的根本,他也可以基於其他可靠的網路傳輸協議實現,不一定需要採用TCP協議(只不過現有的網路傳輸協議中,TCP是使用最廣泛的)
問題錯誤
連接是否有是對session說的,http上不能談有無連接。tcp連接是一次tcp連接會有三次握手,通信是雙工的。和udp相對而言是有面向連接的。
udp是不管對方在不在,按郵件封包方式發過,也不知道對方有沒有收到。
http是在web開始時代,伺服器處理能力比較差。只能來一個連接就會返回信息,然後連接就關閉了,用的是tcp方式通信。這種無連接說的是業務層面的。在高並髮網站中,用長連的tcp,對web伺服器壓力較大,這樣web伺服器相當於遊戲伺服器了,你看看遊戲伺服器多貴就知道了。
現在有WebSocket可以支持在web html5上長連接,如用於網頁遊戲,網頁聯天,或app通信,這樣連接上後和遊戲一樣,不用反覆打開關閉tcp連接。
短連接和長連接,各有優點,要依據業務模型,選擇最優的。我們常說的HTTP是短連接(short-lived),也就是通訊一次就斷開連接,本質上是關閉了TCP連接。在設置過後可以是長連接(在TCP叫long-lived,在HTTP里叫keep-alive),可以依賴一個TCP連接通訊多次並且不斷開。
但是無論長/短連接,本質上都是面向連接。
至於無連接,那個不是HTTP的特性,是UDP的,估計很多人沒區分這兩個詞。
換個角度看,HTTP存在明顯的Client和Server,數據需要往返於二者之間,這也需要一個連接去維持。
TCP好比打電話,你說一句,他說一句,有問有答,有來有回。
HTTP好比寫信,你把信寄過去,他看完信寫了一封回信,信使給你把回信拿回來。over
HTTP伺服器處理完客戶的請求,並收到客戶的應答後,即斷開連接,這就是無連接。
HTTP每次請求不依賴於上一次請求的信息,每個請求都是獨立的,這是無狀態。
送快遞的給你打電話:"請來門口拿快遞!"然後你說「好的!」然後掛電話了。
電話可以只聊一句,所以基於TCP協議可以實現HTTP協議。
連接通信的方式只有兩種:TCP與UDP,前者面向連接,後者無連接。http協議是應用層協議,它與連接或無連接有什麼關係,它只是通信時傳輸的數據的一種格式規範而已,瀏覽器發送http請求時,會將請求按照http協議轉換成相應格式的數據,底層調用面向連接的socket將上述http格式的數據發送給伺服器,伺服器也按照http格式協議解析請求。也可以稱http協議為socket報文格式。
感覺把簡單事情複雜化!tcp協議是水管,http協議是水,水可以時有時無,但一旦有水了,水管可以做到滴水不漏
HTTP雖然佔用TCP連接,但不關心連接: 一次請求-回復的過程不要求TCP在發送請求前位於某個特殊的狀態 (*) ,也不在請求-回復結束後對連接做其他操作。一個客戶端可以收到回復後close(),也可以keep-alive。
* 當然客戶端/伺服器各有狀態,但這些狀態不在TCP這一層
類似的例子: 一個多線程的程序會涉及線程池,同步等諸多東西。但程序內的一個無狀態函數是可以不關心線程的,我們可以說 `exp(x)` 是個無線程函數。
TCP的連接是指單詞會話, 技術性架構連接.
HTTP的無連接是指整個網站的瀏覽過程, 業務性架構無連接.
連接狀態的應用對象完全不同.
HTTP是無狀態的,是不是弄混了?
我覺得吧,無連接是相對應用層來說的!tcp是傳輸層的東東。所以就不怎麼矛盾了!
經常能看到車大神的故事,但我覺得他的這個故事沒有側重於解釋為什麼要這樣,如果不這樣會怎麼樣?所以我個人感覺不利於理解,下面說一說我自己的想法,說的不好或者錯誤地方,還望各位指出並加以斧正。
首先我們來簡單地理解一下什麼叫面向連接,通俗地說,面向鏈接就是雙方都需要經過若干次詢問來確認對方的存在並且是否願意建立連接,只有建立連接以後才能夠開始通信!
可以試想一下假設HTTP如果是面向連接的會怎樣:
應用A要發送一個http請求給應用B,那它必須首先詢問B是否願意與自己建立連接,這是應用層的詢問,封裝到運輸層以後還要先進行三次握手來建立運輸層的連接,然後才能夠將應用層的詢問發出,這樣就重複詢問了一遍!當然,斷開連接也同樣會重複,既然運輸層已經是連接可靠的,所以應用層不需要再去建立連接,這樣是多此一舉!傳輸層和應用層的兩個協議,面不面向連接並不是同一個意思。
http是應用層的 tcp是傳輸層的,http不負責可靠,有序的傳輸,它通過下面TCP來提供的。不過,以前的web時代 http是短連接的
寫一點自己的理解:
HTTP是無連接的,雖然其無連接,但是因為 HTTP 需要極高的可靠性,所以 TCP 是最好的選擇,所以 HTTP 選擇了 TCP 並不是因為 TCP 是有鏈接的,而是因為其可靠性(雖然這種可靠性很大一部分是源於 TCP 是有鏈接的);
比如在最開始的 HTTP1.0 中,每一個請求都需要建立一個新的 TCP 連接,就很容易理解 HTTP 並不需要像 TCP 這樣的保持連接狀態的特性。
子曰,,無為有處有還無
子曰,,udp無連接
貼一篇csdn的文章
如何理解HTTP協議的 「無連接,無狀態」 特點?
http是無連接的,這種說法我今天第一次聽到。我覺得我大學是不是白上了,還是現在培訓班都開始舔著臉騙人也不害臊了?
推薦閱讀:
※服務端把客戶端幾次發的數據一起接受了,是怎麼回事?socket,Tcp協議
※TCP中已有SO_KEEPALIVE選項,為什麼還要在應用層加入心跳包機制??
※TCP面向位元組流和報文段的關係是什麼?
※怎樣實時判斷socket鏈接狀態?
※leader/follower, 半同步半非同步 和 事件驅動的關係是什麼?