第一章 web服務器的工做原理及過程html
1.1基本原理程序員
1、tcp三次握手web
第一次握手:發送請求鏈接包給服務器。客戶端發送syn包(syn=j)到服務器,並進入SYN_SEND狀態,等待服務器確認;編程
第二次握手:服務器收到請求鏈接後,返回一個能夠鏈接的應答包。服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時本身也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;api
第三次握手:客戶端收到應答包後再向服務器端發送收到應答包的確認包。客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。跨域
2、socket瀏覽器
程序經過socket進行通訊。做爲進程通訊機制,用於描述IP地址,端口,是一個通訊鏈的句柄。sochet其實是對tcp/ip協議的封裝,socket自己不是協議,而是一個調用接口(API)緩存
經過Socket,咱們才能使用TCP/IP協議。TCP/IP也要提供可供程序員作網絡開發所用的接口,這就是Socket編程接口。安全
socket函數接口:,好比create、listen、connect、accept、send、read和write等等。服務器
套接字之間的鏈接過程分爲三個步驟:服務器監聽,客戶端請求,鏈接確認。
1、服務器監聽:服務器生成一個監聽socket,實時監聽來訪socket。服務器端套接字並不定位具體的客戶端套接字,而是處於等待鏈接的狀態,實時監控網絡狀態,等待客戶端的鏈接請求。
2、客戶端請求:指客戶端的套接字提出鏈接請求,要鏈接的目標是服務器端的套接字。
爲此,客戶端的套接字必須首先描述它要鏈接的服務器的套接字,指出服務器端套接字的地址和端口號,而後就向服務器端套接字提出鏈接請求。
3、鏈接確認:當服務器端套接字監聽到或者說接收到客戶端套接字的鏈接請求時,就響應客戶端套接字的請求,創建一個新的線程(一個新的socket),把服務器端套接字的描述發給客戶端,一旦客戶端確認了此描述,雙方就正式創建鏈接。
而服務器端套接字繼續處於監聽狀態,繼續接收其餘客戶端套接字的鏈接請求。
3、http協議
1、HTTP/0.9 的特性
只支持html標籤,只支持純文本內容。
只有GET一個方法,能請求簡單的頁面。
2、http/1.0 特性
除支持html標籤之外,引入了MIME,能夠傳純文本之外的內容;
增長了七個方法,從而加強了訪問服務器的方式,使動態網頁訪問方式更多。
(1)MIME
MIME:multipurpose Internet Mail Extension ,多用途互聯網郵件擴展。
在傳輸前,把非文本數據從新編碼爲文本格式,接收方用相反的方式將其從新還原爲原來的格式,還能調用相應的程序打開此文件。
smtp(簡單郵件傳輸協議): 只能傳輸純文本郵件。
在smtp中引入了MIME後能夠傳輸多種文件了。如圖像、視頻等。
將MIME引入到http當中,因此如今的網頁能夠傳輸豐富的文件。
客戶端瀏覽器向web服務器請求數據--》服務器收到請求把響應的文件組織成一個Html文件傳給客戶端時,都在前面加了格式類型(如 p_w_picpath/jpg)--》客戶端覽器收到服務器傳回來的html頁面時,會利用瀏覽器中的相應的插件來打開此html頁面中包含的文件並展現出來(如今瀏覽器能夠解析幾百種文件格式。若是沒有這種文件的插件就沒法打開,如flash,就須要手工安裝插件)
(2)http/1.0的幾個方法:
GET:從服務器獲取資源到本地
POST:提交
head:
PUT:
DELETE:遠程從服務器端刪除某文件。
trace:
options
connection
(3)動態網頁的執行過程:
服務器端存儲的文檔非Html格式,而是編程語言開發的腳本。服務器端腳本接受參數以後(客戶端經過get方法或post方法把參數傳遞到服務器)在服務器運行一次,運行完成以後生成的html格式文檔,再把生成的Html文檔發給客戶端。
動態網頁包含動態網頁和靜態網頁。
3、http/1.1
在http/1.1的基礎上增長了如下兩項功能:
(1)加強了緩存的功能
(2)長鏈接機制
在http1.0中,一次鏈接只能做一次http請求,即請求一次,鏈接一次,請求完成當即斷開鏈接。
http1.1之後,可進行長鏈接,便可以一次鏈接屢次請求,即請求鏈接後就不斷開,後續請求直接傳送。
若是用在請求不是很大的環境中能夠很大的提高訪問性能,但在訪問量大的請況下不建議開啓此功能。
4、http報文
(1)請求報文:
<method><request-url><version> //資源獲取方法,請求的資源是什麼,協議版本號
<headers> //頭部
//空白行,必定要的
<entiy-body> //報文主體
(2)響應報文:
<version><status><reason-phrase> //響應協議版本,狀態代碼,狀態碼解釋。
<headers> //頭部
//空白行
<entiy-body> //響應報文體
狀態碼:
1xx:純信息。
2xx:「成功」類的信息。 200,請求資源正常。
3xx:重定向類的信息。 301,永久重定向; 302,臨時重定向; 304,沒有發生改變。
4xx:客戶端錯誤類信息。 404,請求了一個不存在的文件;
5xx:服務器端錯誤類的信息。
例:
請求報文:
GET /2.html HTTP/1.1 //GET方法/×××器根文件夾下2.html的內容,爲空就是默認網頁/協議版本1.1
Host:www.loready.cn
connection:keep-alive //上兩行都是頭部,主機名是loready,鏈接類型是長鏈接。
響應報文:
HTTP/1.1 200 OK //版本號是1.1 /200狀態碼,即正常/ok即成功。
1.2 asp.net整個訪問過程
1、瀏覽器請求
(1) 瀏覽器中輸入網址訪問某網站
(2) 瀏覽器會把請求的內容封裝成Http請求報文發向服務器端
(3) IIS服務器經過http.sys監聽請求(http.sys運行在內核中)
(4) 當監聽到請求後,會判斷請求的網站是否存在,如存在就把請求轉到IIS的inetinfo.exe
(5)進程若是是初次運行,當前應用程序池中沒有對應工做進程接受請求,會啓動W3WP.exe工做進程
(5) 若是是靜態網頁,w3wp.exe直接讀取磁盤靜態網頁文件返回給客戶端
(7)若是是asp.net動態網頁(會根據訪問報文中的後綴名判斷是否是動態網頁,如.aspx,ashx等後綴)那麼在工做進程w3wp.exe中加載aspnet_isapi.dll這個程序()開啓asp.net請求過程。
----------動態數據封裝階段---------------
Aspnet_isapi.dll開始執行,首先加載.net動行時,啓動.net應用程序域,調用.net類庫。
(8)Aspnet_isapi.dll經過調用IISAPIRuntime.Proce***equest(ecb)方法把把請求數據簡單封裝成ISAPIWorkerRequest類型的對象wr。(IISAPIRuntime是一個接口,經過實現這個接口的類來調用這個接口的Proce***equest()方法來處理請求)
(9)再把wr對象傳遞到httpcontext(wr)構造函數中,將其繼續封裝成httpcontext類的對象。
Httpcontext類中主要有httprequest和httpresponse()方法。
(10)經過調用HttpApplicationFactory.GetApplicationInstance(contex)建立一個HttpApplication對象。而後調用HttpApplication對象Proce***equest()方法開始整個ASP.net處理請求的過程。其實HttpApplication對象就是global.asax這個文件編譯後的類對象。建立HttpApplication對象能夠說就是建立了global.asax這個文件編譯後的結果。
-----------asp.net生命週期,即動態數據處理階段-------------------------------
.net生命週期包含了19個事件和23步驟,經過這一系列的過程來對請求數據進行驗證,判斷是否緩存,建立session,建立頁面對象,執行頁面的proce***equest()方法等處理後把結果返回給客戶端。
第二章通常處理程序
通常處理程序(httphandler):是一個實現了ihttphandler的接口的特殊類,每個實現了ihttphandler的接口的類都可以處理瀏覽器發來的請求,並作出響應。用HttpContext(請求上下文)類的context對象實現處理瀏覽器的請求與響應。其中context.request得到瀏覽器的請求參數,用context.respones響應請求。
1 context.request的成員:
一、 querystring
獲取經過get方式傳來的數據。
Get傳數據的方式:經過url,或者表單的get。
例:
Int age=Convert.ToInt32Context.request.querystring[「txtAge」] //[]中是html頁面中要提交數據的標籤的name值。
二、 form
Convert.ToInt32Context.request.Fom[「key」]
獲取經過post方式傳來的數據。
三、 params
客戶提交的數據集合。既可用於get,也可用於post。
Convert.ToInt32Context.request.Params[「key」]
四、 context.request.mappath()
把網頁文件的相對路徑轉換成絕對路徑。
5、非form標籤沒法經過get或post傳遞參數時,可在form表單中加一個hidden域,把hidden的值設成和非form標籤值同樣,來達到傳遞參數的目的。如:DIV,table等非form標籤。
2 context.respones的成員:
一、 write方法:
直接在頁面上輸出內容。
Response.write(「hello,word」);
二、 redirect方法:重定向響應代碼302
重定向另一個頁面,服務器發送命令讓瀏覽器跳轉。
Response.redirect(http://www.baidu.com);
三、 end方法:
結束輸出。碰到end方法後,後面程序都再也不執行。
context.Response.End();
3 請求數據的方法:
一、 get
get是先參數經過URL傳遞到服務器,參數值會顯示在url欄中。服務器中的通常處理程序(ashx)經過context.request得到請求的參數值,而後用context.response把處理的結果返回給客戶端瀏覽器。也能夠經過表單中的get傳遞參數。
二、 post
post請求報文中有content-type(請求體類型),且沒有緩存的。通常用在登陸界面,或者提交的參數數據比較大的地方。
注意事項:
只有表單元素,而且具備name屬性才能提交。
具備disable屬性不能提交。
當有多個控件的Name屬性的值相同時,就會用逗號分隔開數據顯示出來。
第三章狀態傳遞和保持
Web應用程序是使用HTTP協議傳輸數據的。HTTP協議是無狀態的協議。一旦數據交換完畢,客戶端與服務器端的鏈接就會關閉,再次交換數據須要創建新的鏈接。這就意味着服務器沒法從鏈接上跟蹤會話。即用戶A購買了一件商品放入購物車內,當再次購買商品時服務器已經沒法判斷該購買行爲是屬於用戶A的會話仍是用戶B的會話了。要跟蹤該會話,必須引入一種機制。
一、 cookies
(1)cookies的機制
若是你把Cookies當作爲http協議的一個擴展的話,理解起來就容易的多了,其實本質上cookies就是http的一個擴展。有兩個http頭部是專門負責設置以及發送cookie的,它們分別是Set-Cookie以及Cookie。當服務器返回給客戶端一個http響應信息時,其中若是包含 Set-Cookie這個頭部時,意思就是指示客戶端創建一個cookie,而且在後續的http請求中自動發送這個cookie到服務器端,直到這個 cookie過時。若是cookie的生存時間是整個會話期間的話,那麼瀏覽器會將cookie保存在內存中,瀏覽器關閉時就會自動清除這個 cookie。另一種狀況就是保存在客戶端的硬盤中,瀏覽器關閉的話,該cookie也不會被清除,下次打開瀏覽器訪問對應網站時,這個cookie就會自動再次發送到服務器端。一個cookie的設置以及發送過程分爲如下四步:
因爲HTTP是一種無狀態的協議,服務器單從網絡鏈接上無從知道客戶身份。怎麼辦呢?就給客戶端們頒發一個通行證吧,每人一個,不管誰訪問都必須攜帶本身通行證。這樣服務器就能從通行證上確認客戶身份了。這就是Cookie的工做原理。Cookie其實是一小段的文本信息。客戶端請求服務器,若是服務器須要記錄該用戶狀態,就使用response向客戶端瀏覽器頒發一個 Cookie。客戶端瀏覽器會把Cookie保存起來。當瀏覽器再請求該網站時,瀏覽器把請求的網址連同該Cookie一同提交給服務器。服務器檢查該 Cookie,以此來辨認用戶狀態。服務器還能夠根據須要修改Cookie的內容。
(2)cookie的屬性和特色
cookie的內容主要包括:名字,值,過時時間,路徑和域。路徑與域一塊兒構成cookie的做用範圍。
屬 性 名 |
描 述 |
String name |
該Cookie的名稱。Cookie一旦建立,名稱便不可更改 |
Object value |
該Cookie的值。若是值爲Unicode字符,須要爲字符編碼。若是值爲二進制數據,則須要使用BASE64編碼 |
int maxAge |
該Cookie失效的時間,單位秒。若是爲正數,則該Cookie在maxAge秒以後失效。若是爲負數,該Cookie爲臨時Cookie,關閉瀏覽器即失效,瀏覽器也不會以任何形式保存該Cookie。若是爲0,表示刪除該Cookie。默認爲–1 |
boolean secure |
該Cookie是否僅被使用安全協議傳輸。安全協議。安全協議有HTTPS,SSL等,在網絡上傳輸數據以前先將數據加密。默認爲false |
String path |
該Cookie的使用路徑。若是設置爲「/sessionWeb/」,則只有contextPath爲「/sessionWeb」的程序能夠訪問該Cookie。若是設置爲「/」,則本域名下contextPath均可以訪問該Cookie。注意最後一個字符必須爲「/」 |
String domain |
能夠訪問該Cookie的域名。若是設置爲「.google.com」,則全部以「google.com」結尾的域名均可以訪問該Cookie。注意第一個字符必須爲「.」 |
String comment |
該Cookie的用處說明。瀏覽器顯示Cookie信息的時候顯示該說明 |
int version |
該Cookie使用的版本號。0表示遵循Netscape的Cookie規範,1表示遵循W3C的RFC 2109規範 |
(3)cookie的特性
Cookie的不可跨域名性
www.google.com頒發的Cookie不會被提交到域名www.baidu.com去。正常狀況下,同一個一級域名下的兩個二級域名如www.helloweenvsfei.com和p_w_picpaths.helloweenvsfei.com也不 能交互使用Cookie,由於兩者的域名並不嚴格相同。若是想全部helloweenvsfei.com名下的二級域名均可以使用該Cookie,須要設置Cookie的domain參數.
path屬性決定容許訪問Cookie的路徑(ContextPath),不一樣路徑的cookie不能互訪。如 /var/www/jpe/下的cookie,不能獲取/var/www/mv/下的cookie。如要求能夠互訪,須要設置路徑屬性。
l Cookie的安全屬性
HTTP協議不只是無狀態的,並且是不安全的。使用HTTP協議的數據不通過任何加密就直接在網絡上傳播,有被截獲的可能。使用HTTP協議傳輸很機密的內容是一種隱患。若是不但願Cookie在HTTP等非安全協議中傳輸,能夠設置Cookie的secure屬性爲 true。瀏覽器只會在HTTPS和SSL等安全協議中傳輸此類Cookie。下面的代碼設置secure屬性爲true。
Cookie的maxAge決定着Cookie的有效期,單位爲秒(Second)
正數:即多久後cookie失效。
負數:關閉瀏覽器即消失。
0:則表示刪除該Cookie
l Cookie的修改、刪除
Cookie並不提供修改、刪除操做。若是要修改某個Cookie,只須要新建一個同名的Cookie,添加到response中覆蓋原來的Cookie。
若是要刪除某個Cookie,只須要新建一個同名的Cookie,並將maxAge設置爲0,並添加到response中覆蓋原來的Cookie。注意是0而不是負數。負數表明其餘的意義。讀者能夠經過上例的程序進行驗證,設置不一樣的屬性。
二、 session
(1)session的機制
session機制是一種服務器端的機制,服務器使用一種相似於散列表的結構(也可能就是使用散列表)來保存信息。當程序須要爲某個客戶端的請求建立一個session時,服務器首先檢查這個客戶端的請求裏是否已包含了一個session標識(稱爲session id),若是已包含則說明之前已經爲此客戶端建立過session,服務器就按照session id把這個session檢索出來使用(檢索不到,會新建一個),若是客戶端請求不包含session id,則爲此客戶端建立一個session而且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字符串,這個session id將被在本次響應中返回給客戶端保存。保存這個session id的方式能夠採用cookie,這樣在交互過程當中瀏覽器能夠自動的按照規則把這個標識發送給服務器。通常這個cookie的名字都是相似於SEEESIONID。但cookie能夠被人爲的禁止,則必須有其餘機制以便在cookie被禁止時仍然可以把session id傳遞迴服務器。
(2)session的屬性
Session的生命週期
Session保存在服務器端。爲了得到更高的存取速度,服務器通常把Session放在內存裏。每一個用戶都會有一個獨立的Session。若是Session內容過於複雜,當大量客戶訪問服務器時可能會致使內存溢出。所以,Session裏的信息應該儘可能精簡。
Session在用戶第一次訪問服務器的時候自動建立。須要注意只有訪問JSP、Servlet等程序時纔會建立Session,只訪問HTML、IMAGE等靜態資源並不會建立Session。若是還沒有生成Session,也可使用request.getSession(true)強制生成Session。
Session生成後,只要用戶繼續訪問,服務器就會更新Session的最後訪問時間,並維護該Session。用戶每訪問服務器一次,不管是否讀寫Session,服務器都認爲該用戶的Session「活躍(active)」了一次。
Session的有效期
因爲會有愈來愈多的用戶訪問服務器,所以Session也會愈來愈多。爲防止內存溢出,服務器會把長時間內沒有活躍的Session從內存刪除。這個時間就是Session的超時時間。若是超過了超時時間沒訪問過服務器,Session就自動失效了。
Session的超時時間爲maxInactiveInterval屬性,能夠經過對應的getMaxInactiveInterval()獲取,經過setMaxInactiveInterval(longinterval)修改。
Session的超時時間也能夠在web.xml中修改。另外,經過調用Session的invalidate()方法可使Session失效。
session對瀏覽器的要求
雖然Session保存在服務器,對客戶端是透明的,它的正常運行仍然須要客戶端瀏覽器的支持。這是由於Session 須要使用Cookie做爲識別標誌。HTTP協議是無狀態的,Session不能依據HTTP鏈接來判斷是否爲同一客戶,所以服務器向客戶端瀏覽器發送一個名爲JSESSIONID的Cookie,它的值爲該Session的id(也就是HttpSession.getId()的返回值)。Session 依據該Cookie來識別是否爲同一用戶。
該Cookie爲服務器自動生成的,它的maxAge屬性通常爲–1,表示僅當前瀏覽器內有效,而且各瀏覽器窗口間不共享,關閉瀏覽器就會失效。
所以同一機器的兩個瀏覽器窗口訪問服務器時,會生成兩個不一樣的Session。可是由瀏覽器窗口內的連接、腳本等打開的新窗口(也就是說不是雙擊桌面瀏覽器圖標等打開的窗口)除外。這類子窗口會共享父窗口的Cookie,所以會共享一個Session。
注意:新開的瀏覽器窗口會生成新的Session,但子窗口除外。子窗口會共用父窗口的Session。例如,在連接上右擊,在彈出的快捷菜單中選擇「在新窗口中打開」時,子窗口即可以訪問父窗口的Session。
(3)session經常使用方法
Session中包括各類方法,使用起來要比Cookie方便得多。Session的經常使用方法如表1.2所示。
HttpSession的經常使用方法
方 法 名 |
描 述 |
void setAttribute(String attribute, Object value) |
設置Session屬性。value參數能夠爲任何Java Object。一般爲Java Bean。value信息不宜過大 |
String getAttribute(String attribute) |
返回Session屬性 |
Enumeration getAttributeNames() |
返回Session中存在的屬性名 |
void removeAttribute(String attribute) |
移除Session屬性 |
String getId() |
返回Session的ID。該ID由服務器自動建立,不會重複 |
long getCreationTime() |
返回Session的建立日期。返回類型爲long,常被轉化爲Date類型,例如:Date createTime = new Date(session.get CreationTime()) |
long getLastAccessedTime() |
返回Session的最後活躍時間。返回類型爲long |
int getMaxInactiveInterval() |
返回Session的超時時間。單位爲秒。超過該時間沒有訪問,服務器認爲該Session失效 |
void setMaxInactiveInterval(int second) |
設置Session的超時時間。單位爲秒 |
void putValue(String attribute, Object value) |
不推薦的方法。已經被setAttribute(String attribute, Object Value)替代 |
Object getValue(String attribute) |
不被推薦的方法。已經被getAttribute(String attr)替代 |
boolean isNew() |
返回該Session是不是新建立的 |
void invalidate() |
使該Session失效 |
Tomcat中Session的默認超時時間爲20分鐘。經過setMaxInactiveInterval(intseconds)修改超時時間。能夠修改web.xml改變Session的默認超時時間。例如修改成60分鐘:
<session-config>
<session-timeout>60</session-timeout> <!-- 單位:分鐘 -->
</session-config>
注意:<session-timeout>參數的單位爲分鐘,而setMaxInactiveInterval(ints)單位爲秒。
(4)url重寫機制
常常被使用的一種技術叫作URL重寫,就是把session id直接附加在URL路徑的後面。還有一種技術叫作表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時可以把session id傳遞迴服務器。
<form name="testform"action="/xxx">
<input type="hidden" name="jsessionid"value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
實際上這種技術能夠簡單的用對action應用URL重寫來代替。
總結:
Cookie相似於去醫院看病的病歷本,第次去醫院都上病歷本給醫生看來確認你是哪一個病人,之前的病症。可設定某一頁只能給哪一個醫生看,仍是全部醫生均可以看。多長時間不來看病,這頁病歷就沒有效,醫生不認可。
而session,至關於醫生有一個自已的病歷檔案,每次病人看病就把那個病人的檔案調出來,可是醫生須要你拿病歷本拿來,用以識別你是哪一個病人。
三、 狀態保持
第四章:asp.net生命週期
第五章:模板
第六章:服務器控件
第七章:AJAX