2015年8月14日 星期五

以C語言設計一個支援傳一個網頁含一張圖片的多工 Web Server

這次主要是要先用 [ wireshark ] 抓封包軟體來觀察一個伺服器如何去回應瀏覽器使用者請求,再來處理程式方面的撰寫,之後抓封包來驗證自己的程式是否正確回應

******************概念部分****************************
第一點:  瀏覽器的使用者連線部分要以Server的ip位址和通訊埠(port)去連上伺服器
     127.0.0.1:4700
       伺服器的ip(這邊由於是在本機上操作,因此用迴路ip就行): 伺服器端設定http server 的port

第二點:  瀏覽器與伺服器的互動方式是瀏覽器先發出 [ GET ] 請求伺服器端的index.html檔,伺服器端收到請求之後回覆HTTP/1.0 200 OK 代表請求成功收到且傳送html給瀏覽器端,再依照html檔裡面的資訊(例如圖片)瀏覽器端再去跟伺服器發出 [GET ] 請求來讀取圖片,伺服器再次回覆HTTP/1.0 200 OK。彼此的互動是一來一往的。
      HTTP/1.0 200 OK
        伺服器的http版本為1.0,200 OK為成功收到的狀態碼,不同的狀態碼代表不一樣的訊息

第三點:  在抓封包的時候可能會看到HTTP/1.1 304 Not Modified代表對client的request的回應,而不是HTTP/1.1 200 OK,這是因為只要曾經瀏覽過該webserver的網站時,瀏覽器有個功能就是緩存之前的資料,只要下次再重新瀏覽該webserver,webserver就會比對資料的更新時間,沒改變就回HTTP/1.1 304 Not Modified直接存取緩存資料,可以加快下載瀏覽速度,反之從未瀏覽過的webserver或資料有更動時才會回HTTP/1.1 200 OK,再次從webserver端讀取新的資料到瀏覽器上面。

第四點:   程式方面伺服器端至少需要具備兩個檔案,一個是http server的程式,另一個是html檔( 或者寫在http server裡面,但程式看起來會很冗雜,獨立寫一個html檔方便直接用瀏覽器驗證html檔有無錯誤 )

第五點:   http協定方面是以每一行程式文字敘述藉由\r\n代表一個項目的結束,整個http協定的結束要再增加\r\n再文字程式碼最後面
例如:  code==>  "HTTP/1.0 200 OK\r\n\r\n
    第一個\r\n代表http協定的標頭項(header)若單純如上直接撰寫第二個\r\n在標頭後面,則這個伺服器的http回覆只有標頭而沒有任何的檔案資訊



********************************************************************************

1.   首先是最基本的連線三向交握

2.   Client 連線成功後第一個發出請求的HTTP封包,要求讀取一個html




3.  Server回傳GET成功收到的Response給用戶端


4.   Server端回完Response後關閉與用戶端的連線,等待處理下一次的請求


5.    第二次三向交握( 讀圖 )



6.   Client端讀到HTML檔後,發出GET讀HTML裡面的圖檔的請求,用戶端的第二次GET請求


7. Server回傳GET成功收到的Response給用戶端


============================================

(1)  第一次用select的時候,把select放在處理完GET後的地方,發現client端怎麼都跑不出圖片來而timeout斷線,後來才想到要在client送請求的時候就要下select,讓server做判斷有資料進來,再去做處理請求或者逾時的client要斷線的動作。

再來是一開始不是很懂HTTP協定,以為只要GET和HTTP/寫在裡面就好,但事實上HTTP是看字串最後的\r\n代表一行標頭參數資料的結束,整個HTTP協定結束判斷要再加\r\n,之後的內容才是Body,亂寫參數client端會看不懂而錯誤,參數填錯而圖片跟html如果還能讀的到的原因是伺服器送的資料不再是http協定的格式,會以tcp封包丟給瀏覽器使用者,但變成一般的傳輸資料算是一種bug發生。

以及多次編譯的時候,會跑出bind正使用中而不能編譯檔案,這是因為要下寫ㄧ行程式setsockopt來使bind address能重新被使用的功能,最後是static要加在副函式前面,讓只有這個process內部能使用,避免其他的process用到而產生錯誤。

(2). 從觀察的tcp封包來看,每一次Client所發出的請求而web server端回應完之後就斷線,web server端再與下個請求去做連線、完成處理、回應後再斷線,因此為http1.0,如果是web server是支援http1.1版本,每當client第一次連線後,之後所有的client請求都在這一次的連線中被web server處理完成、回應完後才會斷線。


沒有留言:

張貼留言