TCP/IP協議
跨網絡的主機間通信
在創建通訊鏈接的每一端,進程間的傳輸要有兩個標誌:
IP地址和端口號,合稱爲套接字地址 socket address
客戶機套接字地址定義了一個惟一的客戶進程
服務器套接字地址定義了一個惟一的服務器進程javascript
SOCKET套接字
- Socket:套接字,進程間通訊IPC的一種實現,容許位於不一樣主機(或同一主機)上不一樣進程之間進行通訊和數據交換,SocketAPI出現於1983年,4.2 BSD實現
- Socket API:封裝了內核中所提供的socket通訊相關的系統調用
- Socket Domain:根據其所使用的地址
AF_INET:Address Family,IPv4
AF_INET6:IPv6
AF_UNIX:同一主機上不一樣進程之間通訊時使用
- Socket Type:根據使用的傳輸層協議
SOCK_STREAM:流,tcp套接字,可靠地傳遞、面向鏈接
SOCK_DGRAM:數據報,udp套接字,不可靠地傳遞、無鏈接
SOCK_RAW: 裸套接字,無須tcp或udp,APP直接經過IP包通訊
客戶/服務器程序的套接字函數
套接字相關的系統調用:
socket(): 建立一個套接字
bind(): 綁定IP和端口
listen(): 監聽
accept(): 接收請求
connect(): 請求鏈接創建
write(): 發送
read(): 接收
close(): 關閉鏈接php
Socket通訊示例部分1:服務器端Server-tcpserver.py
import socket :引用socekt的模塊API,相似shell中source
HOST='192.168.36.6'
PORT=9527
BUFFER=4096
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind((HOST,PORT))
sock.listen(3)
print('tcpServer listen at: %s:%s\n\r' %(HOST,PORT))
while True:
client_sock,client_addr=sock.accept()
print('%s:%s connect' %client_addr)
while True:
recv=client_sock.recv(BUFFER)
if not recv:
client_sock.close()
break
print('[Client %s:%s said]:%s' %(client_addr[0],client_addr[1],recv))
client_sock.send(‘I am tcpServer and has received your message')
sock.close()
Socket通訊示例部分2:客戶端Client-tcpserver.py
import socket
HOST='192.168.32.6'
PORT=9527
BUFFER=4096
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((HOST,PORT))
sock.send(‘hello, tcpServer!,I am TcpClient')
recv=sock.recv(BUFFER)
print('[tcpServer said]: %s' % recv)
sock.close()
Socket通訊示例部分3:linux下操做步驟
直接先在服務器端上python Server-tcpserver.py命令開啓服務器端,而後在客戶端上python Client-tcpserver.py命令開啓客戶端便可測試通訊效果。css
HTTP服務通訊過程
HTTP相關術語
- http: Hyper Text Transfer Protocol, 80/tcp (超文本傳輸協議)
- html: Hyper Text Markup Language 超文本標記語言,編程語言
示例:把下面的代碼直接複製並建立一個html後綴文件打開便可,瀏覽器打開的時候會自動渲染顯示效果
<html>
<head>
<title>html語言測試</title>
</head>
<body>
<img src="https://ws1.sinaimg.cn/large/006Bs2dCly1g2zhsy5gysj30gt0b2799.jpg" >
<h1>你好</h1>
<p><a href=https://blog.51cto.com/14228129>個人博客</a>歡迎你</p>
</body>
</html>
- CSS: Cascading Style Sheet 層疊樣式表
- js: javascript
- MIME: Multipurpose Internet Mail Extensions 多用途互聯網郵件擴展
/etc/mime.types
HTTP協議
- http/0.9:
- 1991,原型版本,功能簡陋,只有一個命令GET。
- GET/index.html ,服務器只能迴應HTML格式字符串,不能迴應別的格式
- http/1.0:
- 1996年5月,支持cache, MIME, method
- 每一個TCP鏈接只能發送一個請求,發送數據完畢,鏈接就關閉,若是還要請求其餘資源,就必須再新建一個鏈接
- 引入了POST命令和HEAD命令
- 頭信息是 ASCII 碼,後面數據可爲任何格式。服務器迴應時會告訴客戶端,數據是什麼格式,即Content-Type字段的做用。這些數據類型總稱爲MIME 多用途互聯網郵件擴展,每一個值包括一級類型和二級類型,預約義的類型,也可自定義類型, 常見Content-Type值:text/xml image/jpeg audio/mp3
- http/1.1:1997年1月
- 引入了持久鏈接(persistent connection),即TCP鏈接默認不關閉,能夠被多個請求複用,不用聲明Connection: keep-alive。對於同一個域名,大多數瀏覽器容許同時創建6個持久鏈接
- 引入了管道機制(pipelining),即在同一個TCP鏈接裏,客戶端能夠同時發送多個請求,進一步改進了HTTP協議的效率
- 新增方法:PUT、 PATCH、 OPTIONS、 DELETE
- 同一個TCP鏈接裏,全部的數據通訊是按次序進行的。服務器只能順序處理迴應,前面的迴應慢,會有許多請求排隊,形成"隊頭堵塞"(Head-of-line blocking)
- 爲避免上述問題,兩種方法:一是減小請求數,二是同時多開持久鏈接。網頁優化技巧,如合併腳本和樣式表、將圖片嵌入CSS代碼、域名分片(domain sharding)等
- HTTP 協議不帶有狀態,每次請求都必須附上全部信息。請求的不少字段都是重複的,浪費帶寬,影響速度
HTTP1.0和HTTP1.1的區別
- 緩存處理,在HTTP1.0中主要使用header裏的If-Modified-Since,Expires來作爲緩存判斷的標準,HTTP1.1則引入了更多的緩存控制策略例如Entity tag,If-Unmodified-Since, If-Match,If-None-Match等更多可供選擇的緩存頭來控制緩存策略
- 1.0的緩存機制的利用過時時間問題在於假如客戶端和服務器端的時間不一致致使問題。
- 帶寬優化及網絡鏈接的使用,HTTP1.0中,存在一些浪費帶寬的現象,例如客戶端只是須要某個對象的一部分,而服務器卻將整個對象送過來了,而且不支持斷點續傳功能,HTTP1.1則在請求頭引入了range頭域,它容許只請求資源的某個部分,即返回碼是206(Partial Content),方便了開發者自由的選擇以便於充分利用帶寬和鏈接
- 1.1中的好比說網頁圖片的略縮圖,或者說淘寶的圖片放大功能等,這些圖片傳過來的其實都是原圖片的部分資源。
- 錯誤通知的管理,在HTTP1.1中新增24個狀態響應碼,如409(Conflict)表示請求的資源與資源當前狀態衝突;410(Gone)表示服務器上的某個資源被永久性的刪除
- Host頭處理,在HTTP1.0中認爲每臺服務器都綁定一個惟一的IP地址,所以,請求消息中的URL並無傳遞主機名(hostname)。但隨着虛擬主機技術的發展,在一臺物理服務器上能夠存在多個虛擬主機(Multi-homed Web Servers),而且它們共享一個IP地址。 HTTP1.1的請求消息和響應消息都應支持Host頭域,且請求消息中若是沒有Host頭域會報告一個錯誤(400 Bad Request)
- 長鏈接,HTTP 1.1支持長鏈接(PersistentConnection)和請求的流水線(Pipelining)處理,在一個TCP鏈接上能夠傳送多個HTTP請求和響應,減小了創建和關閉鏈接的消耗和延遲,在HTTP1.1中默認開啓Connection:keep-alive,彌補了HTTP1.0每次請求都要建立鏈接的缺點
HTTP1.0和1.1現存的問題
- HTTP1.x在傳輸數據時,每次都須要從新創建鏈接,無疑增長了大量的延遲時間,特別是在移動端更爲突出
- HTTP1.x在傳輸數據時,全部傳輸的內容都是明文,客戶端和服務器端都沒法驗證對方的身份,沒法保證數據的安全性
- HTTP1.x在使用時,header裏攜帶的內容過大,增長了傳輸的成本,而且每次請求header基本不怎麼變化,尤爲在移動端增長用戶流量
- 雖然HTTP1.x支持了keep-alive,來彌補屢次建立鏈接產生的延遲,可是keepalive使用多了一樣會給服務端帶來大量的性能壓力,而且對於單個文件被不斷請求的服務(例如圖片存放網站),keep-alive可能會極大的影響性能,由於它在文件被請求以後還保持了沒必要要的鏈接很長時間
改進http1.X
HTTPS
- 爲解決安全問題,網景在1994年建立了HTTPS,並應用在網景導航者瀏覽器中。最初,HTTPS是與SSL一塊兒使用的;在SSL逐漸演變到TLS時(其實兩個是一個東西,只是名字不一樣而已),最新的HTTPS也由在2000年五月公佈的RFC2818正式肯定下來。 HTTPS就是安全版的HTTP,目前大型網站基本實現全站HTTPS
- HTTPS協議須要到CA申請證書,通常免費證書不多,須要交費
- HTTP協議運行在TCP之上,全部傳輸的內容都是明文,HTTPS運行在SSL/TLS之上,SSL/TLS運行在TCP之上,全部傳輸的內容都通過加密的
- HTTP和HTTPS使用的是不一樣的鏈接方式,端口不一樣,前者是80,後者是443
- HTTPS能夠有效的防止運營商劫持,解決了防劫持的一個大問題
- HTTPS 中的SSL握手等過程下降用戶訪問速度,可是隻要通過合理優化和部署,HTTPS 對速度的影響徹底能夠接受
SPDY
SPDY:2009年,谷歌研發,綜合HTTPS和HTTP二者有點於一體的傳輸協議,主要特色:html
- 下降延遲,針對HTTP高延遲的問題,SPDY優雅的採起了多路複用(multiplexing)。多路複用經過多個請求stream共享一個tcp鏈接的方式,解決了HOL blocking的問題,下降了延遲同時提升了帶寬的利用率
- 請求優先級(request prioritization)。多路複用帶來一個新的問題是,在鏈接共享的基礎之上有可能會致使關鍵請求被阻塞。 SPDY容許給每一個request設置優先級,重要的請求就會優先獲得響應。好比瀏覽器加載首頁,首頁的html內容應該優先展現,以後纔是各類靜態資源文件,腳本文件等加載,能夠保證用戶能第一時間看到網頁內容
- header壓縮。 HTTP1.x的header不少時候都是重複多餘的。選擇合適的壓縮算法能夠減少包的大小和數量
- 基於HTTPS的加密協議傳輸,大大提升了傳輸數據的可靠性
- 服務端推送(server push),採用了SPDY的網頁,例如網頁有一個sytle.css的請求,在客戶端收到sytle.css數據的同時,服務端會將sytle.js的文件推送給客戶端,當客戶端再次嘗試獲取sytle.js時就能夠直接從緩存中獲取到,不用再發請求了
HTTP2
http/2.0:2015年前端
- HTTP2.0是SPDY的升級版
- 頭信息和數據體都是二進制,稱爲頭信息幀和數據幀
- 複用TCP鏈接,在一個鏈接裏,客戶端和瀏覽器均可以同時發送多個請求或迴應,且不用按順序一一對應,避免了「隊頭堵塞「,此雙向的實時通訊稱爲多工(Multiplexing)
- 引入頭信息壓縮機制(header compression),頭信息使用gzip或compress壓縮後再發送;客戶端和服務器同時維護一張頭信息表,全部字段都會存入這個表,生成一個索引號,不發送一樣字段,只發送索引號,提升速度
- HTTP/2 容許服務器未經請求,主動向客戶端發送資源,即服務器推送(server push)
HTTP2.0和SPDY區別:
- HTTP2.0 支持明文 HTTP 傳輸,而 SPDY 強制使用 HTTPS
- HTTP2.0 消息頭的壓縮算法採用 HPACK,而非 SPDY 採用的 DEFLATE
注意點1(http協議簡介)
- https的創建安全加密的鏈接通道的過程和SSH基本上相同(交換雙方公鑰以及生成隨機數對稱密鑰的過程),它倆都是應用層的用於網路傳輸安全的協議,只不過利用下層的TCP協議傳輸數據(https是http加了SSL協議在應用層和傳輸層之間,不過如今通常把直接和應用層和在一塊兒單獨看作一個協議)。還有mysql,dns,telnet等協議都是應用層協議。
- 判斷是否是應用層協議的就是看看是否是擁有客戶端利用了本身的通訊規則,好比手機上的軟件,微信支付寶等等都有本身的加密通訊協議,都屬於應用層協議。
- 套接字地址是用主機的IP和應用的端口號來組成的,用於應用之間跨網絡通訊。
- linux中的socekt的API相關接口系統調用可用man (2) socket查看,可用於基於socket的網絡通訊的軟件開發的調用,這個API使用C編寫的。
- 只要是基於網絡通訊的應用協議,下面均可利用到socket進行通信,而不只僅包括http協議。
- 上面關於套接字的圖中簡單描述了兩個應用利用socket進行網絡通信的過程。其中創建一個鏈接就須要打開一個socket,還有專門用於負責監聽的socket.
- 特別注意的複習知識點:注意,linux下的1-1024端口號只能用於系統管理員root使用,不能用於普通用戶使用,普通用戶使用的時候會被拒絕權限。
- 好比上面python的例子中就利用的是大於1024的端口所以普通用戶也能夠開啓此socket.再好比myslq的3306端口由於大於1024,所以就可用mysql這個普通用戶開啓使用。
- 可是有些服務好比SSH和http服務想要用普通開啓端口,由於它默認的端口是22和80,小於1024,它們的開啓服務的邏輯是先用root身份開啓服務的主進程,而後再在這個主進程的基礎上用各自的普通用戶(好比http的apache用戶)開啓其餘的端口(小於或者大於1024均可以了),由於它是被主進程開啓的子進程的端口,至關於仍是利用root身份開啓的,只不過用普通用戶來使用。,實際上mysql的子一個進程也是root身份開啓的,後面的子進程才用的普通用戶身份。
- html語句是主要用於靜態頁面(動態頁面須要軟件開發和調用),CSS是爲了將不一樣的各類頁面和設置效果進行統一標準,相似於函數,須要哪一種頁面格式(好比標題,大小,顏色等) 直接調用CSS中的格式便可,這樣就能夠簡化頁面,不須要每個頁面都要單獨編輯設置。
- html,css,javascript都是前端必須掌握的工具
- MIME最初用於郵件中想要支持傳輸更多類型的文件,後來也被拿來用於http協議中了,它的支持格式可在/etc/mime.types中查看,linux中能夠yum provides /etc/mime.types查看,並安裝mailcap-2.1.41-2.el7.noarch包
- MIME其中格式的類別寫法爲 '大類/小類'
- 注意MIME和CSS(html)的區別,CSS也只是一個純文本的格式而已,它屬於mime中的text大類中的一個小類,只不過它標準化了文本格式,用起來方便。
- http1.0中增長了:
- POST:用於上傳文件到服務器端(各類類型文件)
- head:只抓取http的報文頭部信息,get的簡化版命令,不抓取所有信息
- http1.1中又增長了長鏈接功能(非持久鏈接的概念就是每次(TCP三次握手)鏈接以後處理請求完畢以後就斷開,這樣能夠減小服務器的資源佔用,同時可以支持更多用戶鏈接,每次鏈接僅下載完數據執行結果以後就斷開,可是這樣下次鏈接須要從新創建TCO的三次握手),長鏈接就是非持久鏈接的過程當中,一次鏈接能夠支持多個請求,而並不是以前的一次鏈接只能支持一個請求。但終究仍是非持久鏈接,如若沒有請求和數據傳輸的話,過一下子仍是會斷開的。
附加:在windows中的瀏覽器打開調試模式從新刷新就能夠看到一個頁面的各個資源來自的不一樣的服務器,同時還能夠看到其餘的一些信息。java
HTTP工做機制
- 工做機制:
http請求:http request
http響應:http response
一次http事務:請求<-->響應
- Web資源:web resource
一個網頁由多個資源構成,打開一個頁面,會有多個資源展現出來,可是每一個資源都要單獨請求。所以,一個「Web 頁面」一般並非單個資源,而是一組資源的集合
- 靜態文件:無需服務端作出額外處理
文件後綴:.html, .txt, .jpg, .js, .css, .mp3, .avi
- 動態文件:服務端執行程序,返回執行的結果
文件後綴:.php, .jsp ,.asp
- 提升HTTP鏈接性能
- 並行鏈接:經過多條TCP鏈接發起併發的HTTP請求
- 持久鏈接:keep-alive,長鏈接,重用TCP鏈接,以消除鏈接和關閉的時延,以事務個數和時間來決定是否關閉鏈接
- 管道化鏈接:經過共享TCP鏈接發起併發的HTTP請求
- 複用的鏈接:交替傳送請求和響應報文(實驗階段)
HTTP鏈接請求
串行和並行鏈接
串行,持久鏈接和管道
URI
URI: Uniform Resource Identifier 統一資源標識,分爲URL和URNpython
- URN: Uniform Resource Naming,統一資源命名
示例: P2P下載使用的磁力連接是URN的一種實現
magnet:?xt=urn:btih:660557A6890EF888666
- URL: Uniform Resorce Locator,統一資源定位符,用於描述某服務器某特定資源位置
- 二者區別:URN如同一我的的名稱,而URL表明一我的的住址。換言之,URN定義某事物的身份,而URL提供查找該事物的方法。 URN僅用於命名,而不指定地址
URL組成
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<fr
ag>mysql
scheme:方案,訪問服務器以獲取資源時要使用哪一種協議
user:用戶,某些方案訪問資源時須要的用戶名
password:密碼,用戶對應的密碼,中間用:分隔
Host:主機,資源宿主服務器的主機名(用到DNS)或IP地址
port:端口,資源宿主服務器正在監聽的端口號,不少方案有默認端口號
path:路徑,服務器資源的本地名,由一個/將其與前面的URL組件分隔
params:參數,指定輸入的參數,參數爲名/值對,多個參數,用;分隔
query:查詢,傳遞參數給程序,如數據庫,用?分隔,多個查詢用&分隔
frag:片斷,一小片或一部分資源的名字,此組件在客戶端使用,用#分隔linux
URL示例:nginx
1. rtsp://videoserver/video_demo/
Real Time Streaming Protocol
2. https://list.jd.com/list.html?cat=670,671,672&ev=149_2992&sort=sort_totalsales15_desc&trans=1 :搜索
3. http://apache.org/index.html#projects-list :片斷
網站訪問量
- IP(獨立IP):即Internet Protocol,指獨立IP數。一天內來自相同客戶機IP地址只計算一次,記錄遠程客戶機IP地址的計算機訪問網站的次數,是衡量網站流量的重要指標
- PV(訪問量): 即Page View, 頁面瀏覽量或點擊量,用戶每次刷新即被計算一次,PV反映的是瀏覽某網站的頁面數,PV與來訪者的數量成正比,PV並非頁面的來訪者數量,而是網站被訪問的頁面數量
- UV(獨立訪客):即Unique Visitor,訪問網站的一臺電腦爲一個訪客。一天內相同的客戶端只被計算一次。能夠理解成訪問某網站的電腦的數量。網站判斷來訪電腦的身份是經過來訪電腦的cookies實現的。若是更換了IP後但不清除cookies,再訪問相同網站,該網站的統計中UV數是不變的
- 注意不一樣的瀏覽器或者同一個瀏覽器可是不一樣的用戶名密碼(針對同一個網站,由於會形成cookie不一樣),都是會被看作不一樣的UV的,但此時IP相同(假如沒有從新撥號)
網站統計:http://www.alexa.cn/rank/
- QPS:request per second,每秒請求數
PV,QPS,併發鏈接數換算公式:
- QPS= PV* 頁⾯衍⽣鏈接次數(頁面內的二次鏈接請求的小文件等)/ 統計時間(86400)
- 併發鏈接數 =QPS * http平均響應時間
- 峯值時間:天天80%的訪問集中在20%的時間裏,這20%時間爲峯值時間
峯值時間每秒請求數(QPS)=( 總PV數 頁⾯衍⽣鏈接次數)80% ) / ( 天天秒數* 20% )
Web服務請求處理步驟
Web訪問響應模型
一次完整的http請求處理過程
- 創建鏈接:接收或拒絕鏈接請求
- 接收請求:接收客戶端請求報文中對某資源的一次請求的過程
其中的Web訪問響應模型(Web I/O)
- 單進程I/O模型:啓動一個進程處理用戶請求,並且一次只處理一個,多個請求被串行響應
- 多進程I/O模型:並行啓動多個進程,每一個進程響應一個鏈接請求複用I/O結構:啓動一個進程,同時響應N個鏈接請求
實現方法:多線程模型和事件驅動
- 多線程模型:一個進程生成N個線程,每線程響應一個鏈接請求
- 事件驅動:一個進程處理N個請求,能夠是不一樣用戶的請求,分時間片進行處理請求並返還數據便可實現(好比利用CPU功能強大而IO速度慢,中間的多餘時間用於CPU處理更多的請求)
- 複用的多進程I/O模型:啓動M個進程,每一個進程響應N個鏈接請求,同時接收M*N個請求
- 處理請求:服務器對請求報文進行解析,並獲取請求的資源及請求方法等相關信息,根據方法,資源,首部和可選的主體部分對請求進行處理元數據:請求報文首部
<method> <URL> <VERSION>
HEADERS 格式 name:value
<request body>
示例:
Host: https://blog.51cto.com/14228129 請求的主機名稱
Server: Apache/2.4.7
HTTP經常使用請求方式,Method
GET、 POST、 HEAD、 PUT、 DELETE、 TRACE、 OPTIONS
- 訪問資源:
服務器獲取請求報文中請求的資源web服務器,即存放了web資源的服務器,負責向請求者提供對方請求的靜態資源,或動態運行後生成的資源資源放置於本地文件系統特定的路徑:DocRoot
DocRoot 默認: /var/www/html
/var/www/html/images/logo.jpg
https://blog.51cto.com/14228129/images/logo.jpg
web服務器資源路徑映射方式:
(a) docroot
(b) alias
(c) 虛擬主機docroot
(d) 用戶家目錄docroot
- 構建響應報文:
一旦Web服務器識別除了資源,就執行請求方法中描述的動做,並返回響應報文。響應報文中 包含有響應狀態碼、響應首部,若是生成了響應主體的話,還包括響應主體
1)響應實體:若是事務處理產生了響應主體,就將內容放在響應報文中回送過去。響應報文中一般包括:
描述了響應主體MIME類型的Content-Type首部
描述了響應主體長度的Content-Length
實際報文的主體內容
2)URL重定向:web服務構建的響應並不是客戶端請求的資源,而是資源另一個訪問路徑
永久重定向:http://www.360buy.com
臨時重定向:http://www.taobao.com
3)MIME類型:
Web服務器要負責肯定響應主體的MIME類型。多種配置服務器的方法可將MIME類型與資源管理起來
魔法分類:Apache web服務器能夠掃描每一個資源的內容,並將其與一個已知模式表(被稱爲魔法文件)進行匹配,以決定每一個文件的MIME類型。這樣作可能比較慢,但很方便,尤爲是文件沒有標準擴展名時
顯式分類:能夠對Web服務器進行配置,使其不考慮文件的擴展名或內容,強制特定文件或目錄內容擁有某個MIME類型
類型協商: 有些Web服務器通過配置,能夠以多種文檔格式來存儲資源。在這種狀況下,能夠配置Web服務器,使其能夠經過與用戶的協商來決定使用哪一種格式(及相關的MIME類型)"最好"
- 送響應報文
Web服務器經過鏈接發送數據時也會面臨與接收數據同樣的問題。服務器可能有不少條到各個客戶端的鏈接,有些是空閒的,有些在向服務器發送數據,還有一些在向客戶端回送響應數據。服務器要記錄鏈接的狀態,還要特別注意對持久鏈接的處理。對非持久鏈接而言,服務器應該在發送了整條報文以後,關閉本身這一端的鏈接。對持久鏈接來講,鏈接可能仍保持打開狀態,在這種狀況下,服務器要正確地計算Content-Length首部,否則客戶端就沒法知道響應何時結束了
- 記錄日誌
最後,當事務結束時,Web服務器會在日誌文件中添加一個條目,來描述已執行的事務
注意點2(HTTP協議具體過程):
- http打開頁面的具體過程:
- 首先打開頁面輸入域名以後(或者說電擊一個按鈕跳轉頁面),本地的DNS服務器會將其解析成IP地址(這個過程是DNS的過程了),得知IP以後,就會先進行TCP的三次握手創建雙方的可信的相互鏈接。
- 創建了TCP的通道鏈接以後就會通過上面的7個步驟,注意七大步(還有那一張圖示中的)說的第一步的創建鏈接指的是http的請求鏈接,不是TCP的通道鏈接。
- 服務器接受請求以後(這個過程沒那麼簡單,由於多個用戶併發鏈接這一臺服務器等其它問題,不僅僅只有一個用戶),對請求中的要求進行處理(好比get請求等等),而後繼續按圖中走下一步。
- 構建響應的時候要把用戶請求的數據進行http的報文頭部封裝,好比http(index.html),這裏的http報文頭部其實就是應用層的報文頭部,而後通過下一層的TCP頭部,後面的過程就再也不贅述了,最終客戶端解封裝獲得數據。
- 在1中這個下載資源的過程當中有許多種方法(串行,並行,持久,管道化等),注意在上面的圖示中演示的服務器並不只僅指的是同一臺服務器
- 串行就是每次發起請求前,先進行TCP三次握手創建通信鏈接,而後發起一個請求,獲得結果數據,TCP四次揮手斷開;而後進行第二次TCP三次握手...
- 並行下載就是好比說在獲取了index主頁面以後,裏面有其餘的多個圖片或者資源文件,此時要下載他們並不是是上面串行的方式一個接着一個,而是同時並行發起請求(注意這裏的同時發起請求指的是同時對不一樣的服務器進行TCP的3次握手(也就是同時打開本機的多個http請求的端口),而後請求數據,而後TCP四次揮手這樣的過程,這裏的串行和並行並無考慮同一臺服務器的多個不一樣資源的問題,假設同一臺服務器有多個數據資源須要獲取它也是每個資源都進行一次這樣的過程,也就是每一次都只下載一個資源),同時下載並顯示出來。
- 同一臺服務器串行鏈接:相似上面的串行,不過是針對同一臺服務器的不一樣資源,創建屢次TCP鏈接,每次下載同一臺服務器的一個資源,直到最後下載完畢。
- 同一臺服務器持久(長)鏈接:同一臺服務器只創建一次TCP鏈接過程,在這長鏈接的時間段以內串行地把數據所有下載完畢以後再斷開TCP鏈接。
- 同一臺服務器管道化持久(長)鏈接:同一臺服務器只創建一次TCP鏈接,而後再這長鏈接的時間段以內並行地把數據所有下載完畢以後再斷開TCP鏈接
- 注意上面的前兩個的串行和並行是同一個級別,後面3個的是同一個級別;前面指的是獲取資源的服務器創建連接方式,後面指的是對單臺服務器內資源下載的具體行爲過程方式。後者是在前者的基礎上進行的。
- Apache和nginx的服務器接收響應的時候,前者默認是多進程IO模型,後者默認是複用的多進程IO模型。所以後者性能更好(由於進程佔用資源多),但前者更穩定。