HTTP基礎理論

對於基本TCP/IP HTTP的簡單說明


TCP/IP

api→懂原理

通信,tcp高併發

分布式,為服務

微服務⇒RPC⇒內核(socket—→IO) ⇒ BIO,NIO,EPOLL

IO 是連結

消息/請求可不可以複用連結(多路服用單純是狀態=>RW)=>連結不能服用

根據消息或請求狀態判斷使否有連節

假設有一個c(client)有兩個線成,如果同時請求一個服務器,因為HTTP是無狀態
=>回傳的消息並不知道是客戶端的哪一個線成=>因此連結不得複用

正確方式:
先線程鎖死連結,完成釋放後再將鎖打開,其他線程在進行請求

OSI七層模型


從7層參考模型到5層實際模型

五層模型中的應用層包含7層模型中的

  1. 應用層
  2. 表示層
  3. 會話層

⇒應用層可以有不同的通信程序,需要個性化

內核主要圍繞tcp/ip協議⇒內核中包含的五層模型

  1. 傳輸控制層
  2. 網路層
  3. 鏈路層

⇒內核是無法被更動的

EX:


nc =>保持建立一個連接
nc www.google.com =>回車後需要 輸入 方法 網址 協議

GET / HTTP/1.0

並非每個程序的方法都相同=>應用層個性化

任何協議都會需要內存幫忙

nc就是掉用傳輸控制層

什麼是傳輸控制層 ?


TCP協議和UDP協議都在這層

解釋tcp

⇒面相連結的可靠傳輸控制協議

⇒三次握手

什麼叫三次握手?(傳輸控制層

後端先做一個數據包發給對方syn(空的數據包⇒控制

服務端接受後會發syn+ack

後端會發給服務端ack

三次握手後內核會開出內存空間buffer

後端有,服務端也有

而所謂的連接就是雙方所開闢的資源的過程⇒有空間就有連結

站在程序的角度,只能看到內存空間,對空間讀(字節數組)或寫並不明白握手細節

程序只和內存空間打交道

程序連結使用socket底層就是內存和tcp三次握手

socket套接字


fd : 四元組⇒ip:port(客戶端) + ip:port(服務端) 唯一標示

程序拿到的是fd(標示幅)

port(端口號)使用數字來表示數據包,有65535個

例子:

IPA(客戶端)⇒啟用app

IPB(服務端)⇒生成TOCMAT端口號為80

請問IPA對IPB(TOCMAT)能建立多少socket(連接)

/--------------------------------------------/

客戶端具備IPA:1 + IPB:80
服務端具備IPA:1 + IPB:80

能改動客戶端的端口號而總數量的端口號有65536
因此能夠建立的連結為6萬多個

/------------------------------------------/

若服務器建立好,請問消耗多少端口號=>只有一個80

如果有一個客戶端想請求超過6萬多(端口總數)的數量對服務端,請問能否成功
=>能,只要客戶端創造出不同的IP就能超過

/------------------------------------------/

若服務端再出現一個程序nginx:90
請問能否再開連接(端口已被佔滿)=>能,因為服務端端口號不一樣,能夠區分出唯一性
=>socket合法,因此可以再創造6萬多個連接

只要不同ip可以創造無限多個socket

數據傳輸⇒TCP → 三次握手 → 數據傳輸 (需要斷開連接) → 四次分手

什麼是四次分手


有一個客戶端和服務端
當客戶端傳送了一個fin信號給服務端 =>第一次握手
服務端接受後回傳一個fin+ack給客戶端 =>第二次握手

if 在這時候端開連接呢
	 客戶端的資源放掉後,服務端的資源還是保留=>服務端資源無法找到相對應具備關係的客戶端資源=>無法正常連結

當服務端主動向客戶端傳送fin信號時 =>達成第三次握手
客戶端接受後回傳ack給服務端 =>四次分手

第三次握手和第四此可以結合在一起

演示四次分手

使用tcpdump必須登入root =>輸入su後password輸入root
ifconfig =>查看可用網路卡位置
tcpdump =>抓包
curl =>完成連結且GET後輸出並退出

EX:
tcpdump -nn -i any port 80

開啟另一個窗口
curl www.google.com

三次握手建立通訊

[S] = syn

[S.] = syn+ack

[.] = ack

數據傳輸

每一個[P]都會搭一個[.] ⇒不斷出現且length都不一樣代表在拆包

四次分手取決於協議⇒要不要保持連結

傳輸控制層完成握手後發送包必須依靠網路層

網路層⇒走路由表


IP

路由 ⇒ 默認網關⇒數據過來會下一跳⇒到另一個網卡

使用netstat -nr查看所有路由
ping www.google.com =>需要經過網關

ping 127.0.0.2 =>不需要網關

ping的原理:
拿到目標ip後到路由表和遮罩進行匹配(2進位運算) =>遮罩通常為255.255.255.0
然後看是否在Destination有相同地址
if 有 =>到gateway查看
如果出現0.0.0.0代表在局域網,不需要網關

arp -a

查看網路的ip地址所對應到的硬件網卡上的地址

演示

arp -d 192.168.150.2 && curl www.google:80

先刪除內核裡的對應地址再進行請求=>curl調用內核建立握手=>發現沒有位置後調用arp協議=>完成三次握手

監控握手和arp
tcpdump -nn -i any port 80 or arp

完成arp協議後再握手

鏈路層


有一個客戶和服務端
客戶端架了一個路由[路由有自己的mark和地址] =>和客戶端有連線
中間有其他運營商或其他路由器
最後再到服務端

主機的時候=>目標ip->服務器的
				=>mark地址->路由器的(下一跳)

數據包發送給路由器=>和路由表對應(發現不是自己)=>轉發->mark地址會運營商(ip永遠只向服務端)

運營商發現無法匹配(將mark轉成下級[服務端]) =>找到服務器

每跳一次mark都發生變化,ip地址永遠只向服務端

端到端=>ip
節點到節點 =>mark地址
-----------------------------
數據包中出現兩套ip地址=>隧道技術(vpn)

中國想訪問其他國家網站在香港架了一個路由
數據包背著兩個ip,內網是其他國家網站的ip地址,用外網包裝(外網指向香港的路由
所以數據包會先到香港再到其他國家

外網=>外部人經過端口都能訪問
------------------
使用DNAT和SNAT可以改變ip地址

附載均衡器=>轉發
有一個server1(能建立5000連結)和server2(建立5000)在前面有附載均衡
當客戶端傳送資訊會透過附載均衡器分別傳送到server1和server2
=>避免高並發

在附載均衡時,有一個原子性不能被打破
lvs(負載均衡服務器)不會和客戶端握手=>類似路由器

有一個syn=>會發送到lvs轉發的服務端server1
server1回傳給客戶端syn+ack
客戶端傳ack給服務端=>此時lvs不能轉發給非發出最原始的syn的服務器
協議就是約束

Ddos原理

客戶端透過lvs的約束來讓ack只能傳給指定服務端

不斷創造(假)客戶端並瘋狂傳送ack導致服務端過載

當真實訪問服務端的ack發送時就發生請求失敗

RPC


假設有個本機docker具有非常多容器但需要同時請求一個服務端(容器)
此時如果使用握手會造成請求時間過長,速度慢
因此在本機內新增一個容器讓其他容器先連結到他再用他連結到服務器
=>本機內握手時間短
但服務端返回時發現並不知道是哪個客戶端請求=>HTTP無狀態(連結復用,須避免)
因此調用RPC讓無狀態變成有狀態(此時服務端需新增一個rpc位置(容器)讓rpc的客戶端請求->再連結到真實服務端)
=>每個請求傳輸前都掛上request id,服務端返回時變知道是哪個客戶端所傳送的了

IO


為什麼要學習io?

io無處不在(tomcat,redis,kafka,nginx),對於性能至關重要

IO→學習網路通信IO(socket)→BIO NIO 多路複用器

計算機組成原理

按下開機後,第一個程序為內核(硬盤加載進內存)=>內核為程序=>對外管理io設備
內核和程序相當於管理層,內核加載網卡後其他程序可以不用手動加載

開機後,內核加載至內存,cpu執行內核指令後
=>內核會把內核所在地址空間至為內核空間,其他空間為用戶空間
=>啟動保護模式(用戶空間沒辦法訪問內核空間,但內核空間可以完全訪問用戶空間)=>減少對系統破壞

但用戶空間的app會用到內核所管理的外部硬件,因此還是需要有辦法訪問內核
=>中斷,系統調用

App產生系統調用而非函數調用,會將函數轉換成系統(調用)=>使用INT x80(軟體中斷)=>訪問內核
用戶想要訪問內核都需要調用中斷

dtruss指令

http加密

如果明文傳輸內容容易被獲得

C為客戶,S為服務,f為加密函數

使用對稱加密(如果每個都有k就安全,因此單純非對稱加密並不安全)


f(k,data)=x

f2(k,x)=data

C->S 傳輸x

S解密x得data,也能傳輸給Cx

K只有一個,所有人都用相同K,容易被破解

非對稱加密(c對s安全,s對c不安全)


pk所有人都能拿

sk只有服務端能拿

C->S拿pk

f(pk,data)=y

f(sk,y)=data

f(sk,data)=y’->被拿到pk,被破解

f(pk,y’)=data

結合兩種加密(產生中間人問題)


S有pk,sk

使用非對稱加密達成協商獲得k

再使用對稱加密使用k交互數據

C->S拿pk

C加密數據y給S

S解密數據y,並且將y當非對稱加密k

S通知服務端新的K

再使用對稱加密k進行數據交互

看似安全,但可是


黑客如果攔截pk,sk

C拿到黑客的pk,黑客像S請求真實pk

C傳送數據data給黑客加密,再被攔截

被黑客用自己的sk攔截,再傳ok(使用對稱加密

黑客像服務端發送數據(藉由pk加密)請求使用對稱加密,服務端傳送ok

黑客成為C和S的中間人,獲得所有信息

解決中間人問題


因為在第一步被黑客介入,不知道公鑰是否正確

引入CA (檢查公鑰正確性),CA具有cpk和csk

先將pk進行加密

pk=>f(csk ,pk)=license給S

C請求license,得到cpk 就能解密

但C對CA機構拿cpk 有可能被截獲,因此直接將cpk寫死在操作系統C端

因此C端能直接對license解密,然後協商k 接著對稱加密,交互信息

保證pk的絕對安全性

如果此時還有中間人(黑客

獲取證書的部分是不可能介入的,license不安全,出現警告且無法訪問

黑客只拿到pk,當C傳輸時無法解密(需要sk

對稱+非對稱+CA

協商過程


訪問百度

1 C->S 支持SSL版本,非對稱算法,隨機數1

2 S->C 就用SSL版本,對稱算法,隨機數 2,CA證書

3 C認證證書

證書認證成功:

4 C->S 隨機數3,hash(1,2)=xx

5 S驗證xx==hash(1,2)=>隨機數1,2,3生成k

6 S->C hash(1,2,4)=zz

7 C hash(1,2,4)==zz?=>隨1,2,3生成k

5和7的k會相同