[HTTP相關] 解析HTTP封包,瞭解Session ID和3-way handshake(三向交握)

這就是我們一直在用,不管是手機還是瀏覽器
在這虛擬化技術,雲端科技,Web 2.0等等蓬勃發展的年代
只要是上網,一定完全脫離不了Http的關係

對於網路,這是很基底的概念
想要讓技術層面更進一步
可以從日常接觸到的概念開始
讀通了,就很有用

—————————————————————–(以上都是廢話)—————————————————————

好吧,說真的我不大會教網路這種東西
可能有修過網路相關課程的人,可能會比較懂一點

我盡量從觀察到實際結果,配合網路概念解釋一遍 

 

HTTP封包

我先放這次抓HTTP封包的截圖,再來解釋可能會比較有概念一點

2011-10-21 00 09 30.png  

 

這次所使用的軟體是Wireshark,是個抓封包的軟體

http://www.wireshark.org/download.html

裝好之後選擇網路介面然後就可以看到類似像上圖的東西了喔
我想你一定是在看我的文章,你看你的視窗上面有pixnet耶

 


 

講起網路,不免還是從OSI七層開始講起

這個部份我覺得wiki分類的真好  http://en.wikipedia.org/wiki/OSI_model

2011-10-21 00 17 37.png    

有興趣可以點開wiki的連結看,裡面有對應的文章

天音:這時候要像老師一樣諄諄教誨 (雖然我很不想~>"<)

 

OSI七層協定從下到上分別為

實體層(Physical Layer),資料鏈結層(Data Link Layer),網路層(Network Layer),傳輸層(Transport Layer),會談層(Session Layer),展現層(Presentation Layer),應用層(Application Layer)

裡面藍字的內容都是現有協定名字

wiki的目錄,一堆藍字都沒看過沒關係,在這裡,我們只要管  TCP  HTTP  在哪一層就行了


 

對應到我們抓到的HTTP封包

Screen Shot 2012-03-13 at 下午5.36.47  

第一行,是個概覽,這個封包總共收到幾個Frame(訊框)等等

第二行,就是我們收到的Frame(訊框),可以看到我們用Ethernet協定傳送,裡面記錄著最後傳和目標傳到的Mac位址….等等

第三行,就是TCP/IP中的IP協定(Internet Protocol),紀錄著來源和目標的IP等等資訊

第四行,Transmission Control Protocol縮寫就是TCP協定啦,HTTP連線也是基於TCP協定的,可以看到來源和目的的port(連接埠)號

第五行,就是HTTP協定(Hypertext Transfer Protocol)啦

這裡有展開,可以看到完整的HTTP標頭,一個HTTP連線原來附著這麼多的資訊,也是等下要講的重點

第六行,沒甚麼特別的,就只是網頁原始碼

 


封包和傳送原理

封包大概是這樣子的

osi1  

從程式的眼光來看好了,軟體要送個資料到另一台電腦

除了  實體層(Physical Layer) 之外  

會依序從上往下包

你可以想成要送人家禮物要包裝

或想成郵局要送郵務,要在包裹上貼很多標籤

或是辦公室的便利貼,貼一些備註訊息

 

每往下一層就加一些東西上去,到別人的電腦也是這樣,一層層拿掉標籤

最後得到資料

 

HTTP(應用層)也是如此,HTTP是基於TCP(傳輸層)的

在連線的時候也是如此

要先有TCP先連線才會可以跑HTTP的協定

 

 

不要問我為什麼要分那麼多層,網路這東西是有歷史的

很多東西到現今也還在變化 (但這個概念短時間已經是不會變了)

 


先解釋TCP

看到一堆紅線了嗎

分成前三組和後三組

前三組,就是出名的三向交握 (3-way handshake 也有人翻譯三次握手)

(天音:甚麼三向交握都看攏無)

 

看英文比中文意思比較準,意思就是 握手寒暄 啦

 

 

請設想一個情況,想你打skype給朋友
剛接起來網路電話的時候有沒有遇到這樣的情況

[SYN]              我: 哈嚕, 有沒有聽到聲音?

[SYN, ACK]      A: 有聽到,那我呢?有沒有聽到聲音

[ACK]              我: 有滴~

(…….然後開始聊天,喔不是,是傳資料=  =")

 

沒錯,三向交握就這麼簡單

標籤看起來很複雜而已

 

另外這組

[FIN, ACK]

[ACK]

是四向交握協定Four-way Handshake,用來關閉連線的

引用一下文章的內容

1. (B) –> ACK/FIN –> (A)

2. (B) <–     ACK    <– (A)

3. (B) <– ACK/FIN <– (A)

4. (B) –>    ACK     –> (A)

理當要有四個,為何只有二個?我想是Keep-Alive的關係

所以連線沒有斷,保持連線,若有其他的要求就可以馬上繼續連線
而不用重新建立連線


HTTP標頭

HTTP標頭裡面有很多資訊,像是Server的資訊,很明顯是跟Apache做連線

這裡也很清楚看到中間有Set-Coookie: 和PHPSESSID就是Session的ID啦

當Server使用Session時

雖然Session的資料是放在Server上沒錯〈Client看不到〉

為了分辨這個是那個Client連來的
所以會放一個Session ID給Client

(像是你去寄放物品的櫃台寄放東西,櫃台會交給你一把鑰匙一樣)
用鑰匙認顧客

而且這個Session ID會隨著你的連線,在下次要求的時候,放在標頭裡面
一起發送給Server

 

而在網頁設計當中,Session往往都被當成會員登入等依據

當你在清理Cookie的時候,Session ID也一起被你清掉了
也理所當然的被登出了

 

但Session使用上有些限制

  1.  他只能在同一個網域名字下使用,不能跨網域

  2.  Client端要開啟Cookie (當然這項,一般的瀏覽器通常都是開啟的)

  3.  通常Session和Cookie一樣,有Expires(失效時間)的

所以Facebook的認證上考慮到這些限制,才會採用OAuth 2.0

就是模擬Session的原理,只是把Session ID變成token的方式,用HTTP最簡單的GET方式

掛在網址串上面,以做身分的識別

(有關OAuth2.0相關的東西下次再講)


所以Hsuan網友在Android建立HTTP連線裡面

http://j796160836.pixnet.net/blog/post/28994669

問的問題:

 

我在1.php 寫 session 
在2.php echo出session的值
這是沒問題的

但是如果用android端做測試的話
會抓不到session的值
請問這個跟android端有關係嗎??

所以在程式中,Session ID並沒有存下來

 


參考資料:

TCP: SYN ACK FIN RST PSH URG 詳解

https://sites.google.com/site/cimpleteam/articles/tcpsynackfinrstpshurgxiangjie

TCP/IP 概論

http://www2.meps.tp.edu.tw/documents/memo/TCP%EF%BC%8FIP%E6%A6%82%E8%AB%96/index.htm