http的“無連接”指的是_http協議無狀態中的 quot;狀態quot; 到底指的是什么?...

  引子:

  最近在好好了解http,發現對介紹http的第一句話【http協議是無狀態的,無連接的】就無法理解了:無狀態的【狀態】到底指的是什么?!

  找了很多資料不僅沒有發現有一針見血正面回答這個問題的,而且有些解釋還充斥了各種錯誤,看著看著就覺得心里憋著一股濁氣吐不出來

  于是在看了很多資料之后,我一口吐出濁氣,大聲正面提出這個問題:http協議無狀態中的【狀態】到底指的是什么?!

  然后開始不斷探索解決這個問題。。。

  最終很高興的是我找到了讓人滿意的答案,先賣個關子,各位如果著急可以直接拉到最下查看

f3f7d78a7c573777309d4152c33d88a8.png

  正文:http協議無狀態中的【狀態】到底指的是什么?!

  先來看這句話的另外兩個概念:(標準的http協議是無狀態的,無連接的)

  1、標準的http協議指的是不包括cookies, session,application的http協議,他們都不屬于標準協議,雖然各種網絡應用提供商,實現語言、web容器等,都默認支持它

  2、無連接指的是什么

    1、每一個訪問都是無連接,服務器挨個處理訪問隊列里的訪問,處理完一個就關閉連接,這事兒就完了,然后處理下一個新的。

    2、無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,并收到客戶的應答后,即斷開連接。

  對于【無狀態】,我看到很多隔著一層磨砂玻璃一樣的模糊說法(官方或者教程里的說法),看著非常難受(但其實算是對的)(后來我發現我為什么覺得它看著難受了,因為他們引入了很多新的,而且明顯是一個可能用在很多地方的廣義名詞,這些詞最大的作用就是,混淆概念,下面我標注了)

  1、協議對于事務處理沒有記憶能力【事物處理】【記憶能力】

  2、對同一個url請求沒有上下文關系【上下文關系】

  3、每次的請求都是獨立的,它的執行情況和結果與前面的請求和之后的請求是無直接關系的,它不會受前面的請求應答情況直接影響,也不會直接影響后面的請求應答情況【無直接聯系】【受直接影響】

  4、服務器中沒有保存客戶端的狀態,客戶端必須每次帶上自己的狀態去請求服務器【狀態】

  我必須得到確切而具體的解釋!

  這幾點給了我下一步思考的方向:

  1、【服務器中沒有保存客戶端的狀態,客戶端必須每次帶上自己的狀態去請求服務器 】這里的客戶端的狀態是不是確切地指服務器沒有保存客戶的信息呢?但顯然不是啊

  2、【HTTP無狀態的特性嚴重阻礙了這些應用程序的實現,畢竟交互是需要承前啟后的,簡單的購物車程序也要知道用戶到底在之前選擇了什么商品】我對此質疑為什么無狀態就不能實現購物車呢?服務器就不能存儲東西了么?

  3、【 每次的請求都是獨立的,與和是無直接關系的】我覺得這個說法比較靠譜,但是所謂的不同請求間的沒有關系,是指的請求內容沒有關系,還是只是指請求本身沒有關系?

    1、請求內容沒有關系只可能是服務器上不存有用戶數據才可能啊,但是顯然是存有的啊

    2、請求本身沒有關系,這又有什么意義呢,每一次的請求有什么價值?

  根據這個方向我做了一個模擬訪問實驗:假如沒有cookie沒有session,只有http的時候,那當一個注冊用戶訪問這個購物網站的時候,會發生這些事情:

  1、前提情況:

    1、服務器肯定為每個注冊用戶建立了數據表,記錄用戶的數據

    2、http是無連接的

  2、第一步需要登錄

    1、用戶通過http把用戶的用戶名和密碼發送給服務器,服務器把他們跟自己存有的用戶資料對比,如果一致,則返回信息登錄成功

  3、然后用戶點擊某一商品頁

    1、這個動作相當于輸入一個商品頁的網址

    2、假如商品頁比較機密不對外公開,需要是用戶才能訪問

    3、而雖然http能傳送用戶名和密碼,而且剛才也輸入了,還驗證成功了,但是因為服務器既不會記得你登錄的狀態,你的客戶端也不會存儲你剛才輸入的用戶名和密碼

    4、所以因為這一次訪問因為無法確定你的身份,只能訪問失敗。這時候如果要解決這個問題,而且沒有cookie沒有session,那就只能你在訪問網址的同時繼續帶上你的用戶名和密碼(繼續輸入咯)其實就像我現在的APP一樣

  4、假設上一步的問題解決了,就是每次訪問的時候都會手動輸入用戶名和密碼,然后現在的情況是:你已經選了幾件商品在你的購物車中,你想再添加一件商品,于是你點擊某個商品旁邊的加號

    1、這個動作也相當于輸入一個網址,網址的內容是發送一個請求,往你的購物車中加入這個商品

    2、系統首先用你傳來的用戶名和密碼驗證你的身份,然后訪問你的數據庫,在其中的購物車屬性下加一條數據,就是這個商品的數據

    3、操作結束后,返回操作成功,并結束訪問

  5、OK,實驗結束,看似沒有cookie沒有session也能湊合解決問題,其實兩個操作都有很大的問題

    1、你每訪問一次需要權限的內容都需要在客戶端輸入用戶名和密碼,這一項的繁瑣就不必贅述了

    2、你的每一次操作都要與系統底層的數據庫進行交互。多次少量的訪問存在非常大的性能浪費。非常容易就能想到肯定是一次大量的操作更加有效率,于是就想到了緩存區

    3、你的非重要瑣碎數據也被寫進數據庫中,跟你的主要數據放在一起。一次次添加和刪除購物車其實只是跟你這次瀏覽,或者叫這次會話有關,是臨時的數據,跟用戶的主要信息無關,它們沒什么價值,純粹的冗余數據(不排除現在有的公司覺得這種數據也有非常大的價值可以讓它們巧妙的利用),用什么存放這些臨時的數據,我們也很容易想到緩存區

  經過這個模擬訪問實驗,結合前面的思考方向,我們知道了三點:

  1、服務器上肯定存有用戶的數據,你提交的增刪改查它也能夠處理,所以這句話中【服務器中沒有保存客戶端的狀態】的狀態并不是指用戶的數據,我們的猜測不對

  2、我們的質疑對了,無狀態能實現購物車,可以通過服務器上存有的用戶數據來實現

  3、但是,使用上面這種方式實現購物車,存在三個比較大的問題。由此,我們不禁會想,這三個問題的解決是不是跟我們不確切了解的【狀態】一詞有關?于是,接下來我們來通過解決這三個問題來把【狀態】的意義探尋下去

  由上所述,我們可以在http的基礎上增加一些機制來解決上面出現的三個問題

  1、在用戶端增加一個記錄本是非常有必要的,正好官方加入的cookie機制跟這個一樣,它的用處也確實是上面討論的那樣,一般就是用來標識訪問者的身份

  2、在服務器增加一個緩存區能同時解決后兩個問題

    1、有了這個緩存區作為一個數據緩沖,就不用一次次地訪問數據庫,浪費大量計算機資源,而是在最后統一歸入數據庫

    2、有了這個緩存區,你就不用把臨時的數據放到數據庫中了,只需要在你們交流告一段落之后,再把數據整理,把有用的數據歸入數據庫

  3、這里就自然引申出了一個重要的概念:會話,它作為一個緩沖存儲區被從數據庫中分離出來,理由并不生硬,它有其獨特的重要且不可替代的作用。這個東西恰好跟官方加入的session機制一樣

    1、另外說一個非常具有迷惑性的容易讓人對session的主要作用產生偏離的理解:認為session存在的價值就是給訪問者分配一個sessionID代替用戶名和密碼,

    2、為什么非常具有迷惑性,因為session確實做了這件事,而且也起到了很大的作用,所以它是對的,但是只對一半,而且沒有涉及問題的本質,這種情況是最危險的(看似很有說服力,把你說服了,所以你很難有動力繼續找下去,但是真實情況跟它有偏差,但是偏差不大,所以又很難把你說服回來,只有隱隱的不對勁,這個時候你離真實最近,也離真實最遠)

    3、那就順便說說它為什么是對的,也就是用session做的另一件有用的事:

      1、給每個session一個ID,一方面用來方便自己查詢,另一方面把這個ID給用戶,用戶下一次訪問的時候就可以不用用戶名和密碼,而是直接使用這個ID來表明自己的身份

      2、首先,這個ID安全嗎?這個ID比直接傳用戶名和密碼安全嗎?

        1、你很容易會想到,本來用戶名和密碼的組合還特地設置地比較復雜,你這換一組數字就代替了,是不是太不安全了?

        2、我們知道http協議本身是完全不加密的,如果使用用戶名和密碼,第一次訪問是放在http頭中,后邊自動保存了密碼就會放在cookie中,這些都完全沒有加密,它的安全性基本為0,就是裸奔了,只要被竊取,那就丟失了

        3、所以,就這個意義來講,sessionID的安全性跟使用用戶名和密碼沒什么區別

        4、但是其實,雖然http本身不能加密,但是有些軟件什么的,能在應用層面手動給你加密,比如QQ就會使用戶名密碼加臨時驗證碼聯合哈希,sessionID加一個時間戳簡單加密也是非常常用的方法

        5、而且因為sessionID本身有有效期,即使丟了,也可能很快失效,造成的損失可能沒那么大,而用戶名跟密碼丟了,那就大了

        6、所以總結就是:不嚴格加密的sessionID和用戶名和密碼一樣,都不太安全。但是相比較來說,sessionID要安全一些。而使用https是完全安全的。

      3、然后,使用sessionID有哪些好處

        1、方便直接根據ID查詢用戶對應的session

        2、加密的時候計算量小

        3、安全性不會降低,甚至還更高一些

  OK,通過獨立地解決純http機制會產生的問題,我們探討了cookie和session機制的本質。而且想到:【使用http協議,服務器中不會保存客戶端的狀態】所產生的問題通過增加cookie和session機制解決了,是不是就意味著這個【狀態】跟cookie和session的關系非常緊密?所以這個無狀態指的是【沒有對 本次會話 設置一個緩存區,記錄這次會話的狀態,緩存區包括服務器端和用戶端】但好像還是沒有點破關鍵(主要是覺得跟前面那些官方對狀態的說法不太吻合,甚至沒有對應關系)

  忽然我想到一個問題:一個有狀態的http是什么樣的?

  1、很難直接想象有狀態的http是什么樣,因為http這種機制是天然無狀態的

  2、那就類比一下吧,另一個天然有狀態的機制叫TCP。如果有狀態的意思是它的每次請求是有聯系的,那么有狀態的TCP的樣子是:假如一份數據分了三份TCP包發送,那這個包上面會標明這是第幾個包,會標明這個包跟那幾個包是有聯系的,有什么聯系

  3、但好像這個有狀態的TCP跟我們想要的有狀態的HTTP沒有關系,因為即使每次http請求之間互相有聯系,它也不能解決上面提到的http無狀態的問題

  4、誒,等等,好像能類比:

    1、假如每個http連接都有一個簽名,于是第一次登陸成功之后,服務器就知道了這個簽名是允許登陸的,于是之后所有同樣簽名的http連接都能登陸,這里利用了同一個用戶發出的http連接之間的同主人關系,這里解決了一個保持登錄狀態的問題

    2、同樣,來嘗試利用這個【每次http請求之間互相有聯系】來解決上面碰到的那個問題【每一次操作都要與系統底層的數據庫進行交互】,但想了半天確實無法進行下去

    3、不過我靈機一動,從另一個角度來想,好像解決了這個問題:

      1、只有【每次http請求之間互相有聯系】這個條件,無法解決【每一次操作都要與系統底層的數據庫進行交互】

      2、因為很明顯,要解決【每一次操作都要與系統底層的數據庫進行交互】就必須在服務器端開辟一塊緩存區

      3、不過如果你思考一下如何實現【每次http請求之間互相有聯系】,你就會發現,它也需要在服務器端開辟一塊緩存區

      4、所以【在服務器端開辟一塊緩存區】才是真正的條件,也就是說,它確實等價于【有狀態】

      5、而且我也找到了這個【在服務器端開辟一塊緩存區】的條件跟前面那些官方對狀態的說法對應的點,那就是:通過在服務器端開辟一塊緩存區,存儲、記憶、共享一些臨時數據,你就可以:

        1、協議對于事務處理有記憶能力【事物處理】【記憶能力】

        2、對同一個url請求有上下文關系【上下文關系】

        3、每次的請求都是不獨立的,它的執行情況和結果與前面的請求和之后的請求是直接關系的【不獨立】【直接關系】

        4、服務器中保存客戶端的狀態【狀態】

      6、所以,這個狀態,加上前面說的客戶端也有cookie,就是指,客戶端和服務器在臨時會話中產生的數據!而前面也說道了,使用緩存區保存臨時會話中的數據是多么重要

        1、所以狀態不僅包括不同URL訪問之間的關系,還有對其他URL訪問的數據記錄,還有一些其他的東西,所以更確切地說,狀態應該是【實現了這些東西所憑借的后面的緩存空間】中的客戶的臨時數據

        2、cookie和session應該是完全實現了有狀態這個功能

  一種常見的對狀態的誤解:

  1、有人在解釋HTTP的無狀態時,把它跟有連接對立,說是兩種方式,也就是如果想不無狀態,就必須有連接,但其實不然

  2、有連接和無連接以及之后的Keep-Alive都是指TCP連接

  3、有狀態和無狀態可以指TCP也可以指HTTP

  4、TCP一直有狀態,HTTP一直無狀態,但是應用為了有狀態,就給HTTP加了cookie和session機制,讓使用http的應用也能有狀態,但http還是無狀態

  5、開始TCP是有連接,后來TCP無連接,再后來也就是現在TCP是Keep-Alive,有點像有連接

作者:賽艇隊長

https://www.cnblogs.com/bellkosmos/p/5237146.html

e2f01802ecfb8cc2fe45d2fb3ea72506.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374409.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374409.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374409.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

個人日志-7.4

姓名 劉鑫 時間 2016.7.4 學習內容 完善需求分析報告。撰寫數據庫設計說明書。初步安排計劃概要設計說明書。調整項目開發計劃說明書。 所遇問題 無 解決方案 無 轉載于:https://www.cnblogs.com/liuxin13070013/p/5641967.html

通達信編程實例

1、放量a、今日比昨日的成交量放大了1倍:VOL/REF(VOL, 1)>2; b、今日的五日均量比五天前的五日均量放大了3倍:AA:MA(VOL, 5);BB:REF(AA, 5);AA/BB>4; c、今天的成交量達到了整個流通盤的10%以上(注意,10%的表達式是10/100或…

STM32F1筆記(五)外部中斷EXTI

STM32的每個IO都可以作為外部中斷的中斷輸入口。 STM32F103的中斷控制器支持19個外部中斷/事件請求。每個中斷設有狀態為,每個中斷/事件都有獨立的觸發和屏蔽設置。 STM32F103的19個外部中斷為: EXTI線0~15:對應外部IO口的輸入中斷。 EXT…

您不想錯過的十大Java書籍

我們通過閱讀書籍并進行實驗來學習。 因此,必須選擇最佳的可用選項。 在本文中,我想與一些書分享我的經驗,以及它們如何幫助您發展為Java開發人員。 讓我們從頭開始,對于任何Java學生來說,前三本書都是一個很好的起點。…

pythonos模塊_Python3 入門教程——os模塊使用(文件/目錄操作)

前言 os模塊是Python標準庫中一個用于訪問操作系統的功能模塊。 使用os模塊中提供的接口,可以輕松實現跨平臺訪問。 在os模塊中提供了一系列訪問操作系統功能的接口,如,新建目錄、刪除目錄、變更目錄、重命名目錄.... 新建單級目錄 基本語法&…

當數據量很少的時候,tableview會顯示多余的cell--iOS開發系列---項目中成長的知識二...

當數據量很少的時候,tableview會顯示很多的cell,而且是空白的,這樣很不美觀 所以使用下面的方法可以去掉多余的底部的cell 原理是:設置footerView為frame 是 CGRectZero ,造成一種假象! UIView *v [[UIView alloc] initWithFrame:CGRectZero]; [self.myTable setTableFooterVi…

逗牙搞笑網www.idouya.xin

有一天,小明問媽媽“媽媽,媽媽,爸爸是什么啊?”媽媽剛剛和爸爸吵架,生氣的回答“孩子,記住所有的男的都是色狼!”小明有去問爸爸“爸爸,爸爸,媽媽是什么啊?”…

STM32F1筆記(六)獨立看門狗IWDG

STM32F1內置了兩個看門狗,獨立看門狗IWDG和窗口看門狗WWDG,可以用來檢測和解決由軟件錯誤引起的故障。 IWDG最適合應用于那些需要看門狗作為一個在主程序之外,能夠完全獨立工作,并且對時間精度要求較低的場合。WWDG最適合那些要求…

在JSF 2中對定制驗證器進行參數化

在JSF 2中編寫自定義驗證器并不復雜。 您實現Validator接口,添加FacesValidator批注,并在faces-config.xml中插入Validator聲明, 僅此而已 。 一塊蛋糕。 但是,讓我們考慮以下情形: 您需要自定義日期驗證器&#xff0c…

python繪制散點圖的函數_python matplotlib更新函數的散點圖

有幾種方法可以對matplotlib圖進行動畫處理.在下文中,我們將使用散點圖查看兩個最小示例. (a)使用交互式模式plt.ion() 要進行動畫制作,我們需要一個事件循環.獲取事件循環的一種方法是使用plt.ion()(“交互式打開”).然后需要首先繪制圖形,然后可以循環更新繪圖.在循環內部,我…

偷學來的資料

--矛盾 fis3的pngcrush不支持你的node版本v4.4.0 換成4.2.4就可以了. --工具 淘寶 NPM 鏡像:http://npm.taobao.org/ FIS2 to FIS3:https://github.com/fex-team/fis3/blob/master/doc/docs/fis2-to-fis3.md fis3demo:https://github.com/fex-team/fis3-demo --前端blog/網站 廖…

Java EE6事件:JMS的輕量級替代品

我今天要討論的功能是Java EE 6中的事件機制。一般的想法是觸發一個事件,并讓事件監聽器來接收它。 我創建了這個完全沒有用的示例,但是它的簡單性幫助我專注于重要的內容。 我將從后備操作中觸發LogEvent,該事件將記錄到java.util.Logger中。…

STM32F1筆記(七)WWDG窗口看門狗

窗口看門狗與獨立看門狗最大的不同是中斷,窗口看門狗擁有一個提前喚醒中斷。也就是在快要產生復位的前一段時間(T[6:0]0x40)來提醒需要進行喂狗,否則將復位。因此當窗口看門狗的計數器值減到0x40的時候,產生中斷&#…

求助!求助!網站頁面圖片太多,加載時間太長該怎么辦?

以下是百度統計的診斷,小弟萬般無奈,html上的緩存以及圖片處理技巧欠缺,希望各位大大幫幫忙支個招! 以下元素可在不損失原信息量的前提下進行壓縮: http://www.5atl.com/Style/main.css (大小: …

groovy怎樣從sql語句中截取表名_Mysql和SQL

基本概念1.數據庫DataBase簡稱:DB2.什么數據庫?——用于存儲和管理數據的倉庫。存儲過程是一個預編譯的SQL語句,優點是允許模塊化的設計,就是說只需創建一次,以后在該程序中就可以調用多次。3.數據庫的特點&#xff1a…

使用java.util.prefs.Preferences代替java.util.Properties

典型的應用程序安裝程序需要向用戶詢問幾個選項,其中一些是配置問題,例如,應用程序應在其上運行的端口,應如何運行等。應用程序必須記住這些選項,并在每個選項中使用它們。跑。 解決此問題的標準方法是將這些選項寫入屬…

STM32F1筆記(八)時鐘

STM32有五種時鐘源 1、HSI。高速內部時鐘,RC振蕩器,頻率為8MHz。 2、HSE。高速外部時鐘,可接石英/陶瓷諧振器,或者借外部時鐘源,頻率范圍為4MHz~16MHz。 3、PLL。鎖相環倍頻輸出,其時鐘輸入源可選擇為HS…

java常用工具類(一)

一、String工具類 package com.mkyong.common; import java.util.ArrayList; import java.util.List; /** * * String工具類. <br> * * author 宋立君 * date 2014年06月24日 */ public class StringUtil { private static final int INDEX_NO…

Oracle定時器調用存儲過程

關于Oracle定時器調用存儲過程的一點總結&#xff0c;如果有不足的地方&#xff0c;希望大家多多指導&#xff0c;也是第一次在博客上寫東西&#xff0c;以前也只是自己總結之后放在硬盤了&#xff0c;后來同事告訴自己&#xff0c;其實寫博客可以獲得很多&#xff0c;不管是知…

python可以下載百度文庫_不用下載券也能下載百度文庫資料,Python幫你輕松搞定...

大家可能平時都有在百度文庫下載文檔的經歷&#xff0c;費盡心思好不容易在文庫找了一份可以用的資料&#xff0c;一看需要用下載券下載&#xff0c;搞的人很煩。 有的人為了節省時間&#xff0c;就任性辦理了個文庫VIP&#xff0c;再也不用糾結怎么下文檔了。如果你是一個百度…