Java 基礎課七:網絡通信協議

DNS 和 CDN

  1. DNS,域名解析系統,將域名解析爲 IP;
	域名解析,首先會在瀏覽器緩存中查找,然後在操作系統緩存查找, jvm 也會緩存 dns 結果
	如果都沒找到,會到 LDNS 服務器查找,LDNS 是電腦上網配置 IP 時設置的,服務器一般由公司或者運營商提供
	最後通過根域名服務器,返回一個主域名服務器,主域名服務器返回一個 NameServer 域名服務器,即域名的註冊服務器,最終返回解析結果

	上述任何一步,如果找到域名和ip的匹配記錄,就不再查找,並且會將返回結果,在 LDNS,操作系統,和瀏覽器中進行緩存;
  1. 清除 DNS 緩存,window 通過 ipconfig/flushdns,linux 通過 /etc/init.d/nscd restart;

  2. CDN 是內容分發網絡,節點遍佈全國,是非常重要的靜態數據緩存網絡,將靜態數據緩存到離用戶最近的節點,淘寶 90% 數據都是由 CDN 提供;

網絡分層

  1. 四層通信模型,應用層,傳輸層,網絡層,數據鏈路層,每一層都下一層的數據基礎上,加上自身層的數據;
	應用層,通常運行 Ftp 協議,Http 協議,是約束數據通信的格式
	傳輸層,運行 Tcp 協議,Udp 協議,是約束數據通信完整性和可靠性
	網絡層,運行 ip 協議,解決的是局域網之間的互聯
	物理層,運行以太網協議,解決的是電子信號組成數據包,進行點對點通信

IP 協議

  1. 網絡消息在網關,代理服務器之間不斷轉發,ip 協議提供了路由尋址的功能,每一個 ip 地址,標識了網絡上的一個通信設備;
	InetAddress ip = InetAddress.getByName("www.baidu.com");
	InetAddress ip = InetAddress.getByAddress(new byte[]{127,0,0,1});
	如果使用 InetAddress 解析域名,要使用單例模式,避免每次創建 InetAddress 耗時
	使用 url 表示資源地點,uri 表示資源,url 是 uri 的子集;
  1. ip 協議,無法提供消息到達次序,是否損壞,可靠性保證等功能,爲此引入 tcp 和 udp 協議,提供消息可靠性的保障,並且傳輸層提供了複用和分組功能,使得同一設備上的應用,可以複用同一個傳輸層;
	ip + 端口,標識了通信設備上的一個應用

TCP 協議

  1. TCP 協議,面向連接,保證可靠的消息傳輸, 提供全雙工,一對一通信;
	一個以太網數據包的大小是 1522 byte,其中 1500 byte 是負載 payload ,22 byte是頭信息 head 
	負載中 ip 數據包頭信息大概 20 byte,所以 tcp 數據包是 1480 byte,除去頭信息大概 20 byte,是 1460 byte,實際大概 1400 byte,這是一個 tcp 數據包最大的容量,所以在發送 > 1400 byte 的數據時,就必須分包,給每個包編號,接收時數據包需要重組;
  1. TCP 消息頭部,包含源端口號,目的端口號,序列號,確認號,報頭長度,標誌符,接收窗口大小等信息,其中 20 字節固定長度,和 20-40 字節變化長度;
	接收窗口大小,用於流量控制
	tcp 會給消息的每個字節進行編號
	序列號是,當前 tcp 發送數據的第一個字節號
	確認號是,期望收到的第一個字節號,這表示該字節號之前的數據,已全部被接收
	標識符 SYN,用於建立 tcp 連接
	表示符 FIN,爲 1 表示這是釋放連接的報文
	標識符 ACK,爲 1 表示確認號有效,規定 tcp 連接建立之後,報文的 ack 都必須置1
	標識符 URG,爲 1 表示包含緊急消息,且緊急消息一定位於發送數據的最前面,緊急指針指向緊急數據的尾部
	標識符 PSH,爲 1 表示立即將數據交付給應用程序,而不必等到緩存區滿
	標識符 RST,爲 1 表示 tcp 連接出現問題,需要重連

  1. 三次握手建立連接,通信開始前,客戶端和服務端都需要創建自己的 TCB 塊,用於傳輸控制,隨後服務器進入 listen 狀態;
    1. 客戶端向服務端發送建立連接請求報文,頭部 SYN=1, ACK=0, seq=x,雖沒有數據發送,但要消耗一個序號
    2. 服務端接收到請求,響應 SYN=1, ACK=1, seq=y, ack=x+1,表明服務端向客戶端發送的第一個序號是y,已經接收到序號 x,期望下一個 x+1;
    3. 客戶端接收同意連接響應,發送確認報文,syn=1, seq=x+1, ack=y+1
    4. 在此之後客戶端和服務器,都進入 established 狀態,完成三次握手,開始傳送數據。
  1. 三次握手中的前兩次,可以確認服務端可以接收數據,客戶端可以發送數據,通過第三次握手,確保客戶端可以接收數據,服務端可以發送數據,同時避免了連接超時,第一次握手服務端建立了連接,而客戶端已經關閉;
	如果只有兩次握手,客戶端的第一次握手,如果超時還未到達服務端
	此時客戶端發起第二次握手,併成功完成一次通信,客戶端關閉,此時第一次握手達到服務端,服務端建立連接,但卻收不到客戶端的請求,因爲客戶端已經關閉
	通過三次握手,可以避免這種情況,只有客戶端同意連接確認,纔會建立連接
  1. 釋放連接,四次揮手,前兩次揮手用於斷開一個連接,後兩次揮手用於斷開另一個方向連接;

  2. Java 使用 Scoket 和 ServerSocket,進行 tcp 通信,可以設置連接超時時間和通信超時時間;

	connect-timeout,超過該時間,建立連接操作會失敗
	read-timeout,超過該時間,請求-響應操作會失敗

upd 協議

  1. udp 協議,在 IP 協議的基礎上,提供少量的功能,特點面向報文,不分割消息,無需建立連接,可靠性無保證,支持多對多的通信,udp 的消息頭部包含源端口,目的端口,udp 長度,udp 校驗和等;

  2. Java 使用 DatagramSocket 進行 udp 通信;

	// DatagramPacket:“集裝箱” 數據報,包含了其發送的地址
	DatagramSocket:receive(DatagramPacket dp)send(DatagramPacket dp)

Http 協議

  1. 無狀態的短連接,請求-響應模型,一次請求,一次響應,即構成一個連接,http 通信端口,默認是 80,https 通信端口,默認是 443;

  2. 從 http1.1 之後,默認是 keep-alive 長連接,通過 connection:keep-alive 指定,長連接是指一次 http 請求後 tcp 連接不會斷開,會被複用,避免了多次創建 tcp 連接的開銷;

	長連接的斷開,是等到一方明確斷開連接,或者服務器設置 keep-alive 的 timout 時間到,並且這個時間每一次請求都重新計時,更多 keep-alive,參考 https://www.cnblogs.com/freefish12/p/5394876.html 和https://www.jianshu.com/p/3fc3646fad80;
  1. 協議內容,請求由請求行,請求頭,空行,請求體組成,響應由響應行,響應頭,響應體組成;
	請求行:GET url Http1.0
	請求頭:host,user-agent,content-type,accept
	空行
	請求體:key=value&key2=value2

	響應行:HTTP/1.1 200(狀態碼) OK
    響應頭:content-type,content-length,date
    響應體:html...
  1. 請求頭和響應頭信息;
通用的頭部信息:
	cache-control:no-cache 向源服務器驗證,no-store 不緩存,max-age=[X秒] 表示緩存有效期,public(可向任意方提供響應緩存),private(僅向特定用戶返回響應),no-cache(緩存前確認有效性)
    Connection:clost/keep-alive 表示短連接和持久連接,upgrade 表示 upgrade 這個首部僅單次轉發      
    Date:創建報文的日期
    Trailer:表示報文 body 之後的首部字段,常用在分塊傳輸編碼中
    Upgrade:檢測是否可用其他協議通信,使用時結合 Connection:upgrade,通常在 101 響應返回

請求頭信息:
	Accept-Charset:表示客戶端可以接收的字符集
 	Host:表示請求的主機和端口號
 	Accept-Encoding:表示客戶端可接收的內容編碼,如 gzip
 	User-Agent:表示客戶端的操作系統,和瀏覽器等信息
    Host:必填,因爲虛擬主機的存在,ip 地址僅能定位物理機器,結合 Host 定位應用

響應頭信息:
	Server:表示服務器的類型,如 Apache/1.3.6(Unix)
	Content-Length,表示響應體 body 的長度;
	Content-Type,表示響應體 body 的媒體類型,如 text/html,charset=GBK;
	Keep-Alive,表示保持連接的時間;
    Location:重定向時使用
   	Expire:指定資源失效日期,cache-control的max-age優先級更高
    cookie:domain,path,secure,httpOnly
    chunked-Transfer:允許消息分塊發送,每一塊消息一個 http 請求
    range和content-range:用來對資源的部分請求
  1. 響應狀態碼有:
	1XX,請求正在處理
	2XX,表示成功
	3XX,表示重定向,幾乎所有瀏覽器在收到301302303後,都會把post改爲get,刪除請求報文主體,自動再次發送請求
		301:永久重定向,
		302:臨時重定向,
		303:重定向並且用get方法
        304:資源沒有改變,請求中帶有 if-match,if-modified-since 頭部時,不滿足情況下的返回
        307:臨時重定向,瀏覽器通常不會將get改爲post
	4XX,表示客戶端錯誤
		400:請求有語法錯誤,
		403:服務器拒絕提供服務,
		404:請求資源不存在, 
		401:訪問爲授權的資源,響應會攜帶 www-authenticate 頭部,通常瀏覽器收到該響應會彈出認證對話窗口,
	5XX,表示服務端錯誤
		500:服務端內部錯誤
		503:服務器正忙或在停機維護,最好加上 retryAfter 字段返回給客戶端         
  1. 代理和網關,都是消息轉發,代理的設備,接收客戶端請求和服務器響應,在首部 via 寫入來源,進行轉發,有緩存,訪問控制,獲取訪問日誌等功能,並且網關還可以將 http 請求轉換成其他協議,進行通信;

Https

  1. https 是在 http 的基礎上,通過加密,證書,和完整性約束來保證通信安全;

  2. https 的加密,既使用到非對稱加密,又使用到對稱加密,非對稱加密用來傳遞對稱加密的密鑰,保證了絕對安全,對稱加密保障加密的效率;

  3. 服務器的證書,包含公鑰和簽名,簽名可以確保公鑰的不可篡改,公鑰和服務器自身的私鑰,用於非對稱加密;

	證書,既可以向機構申請,也可以自己製作,區別是機構證書,瀏覽器可以直接認證,自己製作的證書,瀏覽器會彈出一個窗口,要求操作者信任
  1. 通信過程:
	1.客戶端發送 https 請求,通常請求 443 端口
    2.服務端向客戶端發送證書
    3.客戶端收到證書後,驗證其有效性,是否過期,是否權威頒發,通過瀏覽器內嵌權威的公鑰,來驗證簽名是否一致,如果不一致,即證書無效,彈出一個警告框,要求用戶信任
    4.然後客戶端會生成對稱加密的祕鑰(隨機值),使用服務器簽名的公鑰,對隨機值進行加密,併發送給服務端
    4.服務端收到後,用自己的私鑰解密,這就是之後對稱加密的祕鑰
    5.這樣客戶端和服務端就都安全的擁有了對稱加密的祕鑰,之後通信使用對稱加密即可

Http 緩存

  1. 由 Pragma: no-cache(1.0),Cache-Control,Expires,Last-Modified,If-Modified-Since,etag 等 http 頭信息控制;

  2. cache-control:private/public 緩存響應內容, public 是指可向任意方提供,private 是指僅向特定用戶

  3. max-age=x 表示緩存時間, expire + 具體時間,表明在指定時間後過期,注意如果在 Cache-Control 響應頭,設置了 max-age 或者 s-max-age,那麼 expires 會被忽略;

  4. if-none-match + etag,請求時得到一個 etag,這樣下次請求攜帶 if-none-match,如果沒改變,返回 304,有改變,正常返回;

  5. last-modified + if-modified-since,和if-none-match + etag:第一次請求,得到返回頭信息 cache-control:max-age:1000;etag:1234;last-modified:20181010,這樣第二次請求,會攜帶 if-none-match:1234;if-modified-since:20181010,服務器就會判斷資源的 etag 與請求頭的 etag 是否一致,資源更新時間是否一致,如有改變,返回 200 和響應內容,無改變,返回304;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章