
您好,我是南橘,萬法仙門的掌門,剛剛從九州世界穿越到地球,因為時空亂流的影響導致我的法力全失,現(xiàn)在不得不通過這個平臺向廣大修真天才們借去力量。你們的每一個點贊,每一個關(guān)注都是讓我回到九州世界的助力,兄弟萌來為我注入修為吧!關(guān)注WX號:南橘ryc 。在公眾號上,除了可以看到云小霄的照片,李小庚的畫像也很快出爐哦。
等我回去以后,大家都是萬法仙門的長老,我會給大家數(shù)不盡的天材地寶,人人如龍,全民飛升。
“云小霄,你的神經(jīng)中樞是不是有問題?!?/p>
在第一百二十八次看到云小霄在沒有任何外物的情況下趴在榻榻米上,像一個蛆一樣的扭動的時候,李小庚終于忍不住開口了。
“沒大沒小的,你才有問題!你全家都有問題!”云小霄隨手撿起榻榻米上的零食砸向李小庚,然后繼續(xù)發(fā)出陣陣傻笑。
“那你怎么現(xiàn)在扭的像個蛆一樣?以前每天趴在地上拿著平板打游戲也就算了,這段時間天天看你對著空氣傻笑,是不是腦子壞掉了?”
“呸!你才腦子壞掉了,怎么來萬法仙門兩年了還這么純純的?有空記得看看新聞,萬維仙網(wǎng)這段時間新推出了云游戲云電影模式,只需要達成連接,就可以通過云服務(wù)直接訪問網(wǎng)絡(luò)服務(wù)哦,甚至連客戶端都不需要了?!痹菩∠隹窗装V一樣看著李小庚。
李小庚一臉哀怨的望著云小霄:“你不是說結(jié)丹之前不讓我上網(wǎng)嗎,別的師兄師弟天天在網(wǎng)上打游戲聊天,只有我連領(lǐng)個文具都得線下排隊。”
“我還不是為了你好?”云小霄雙手叉腰:“行吧行吧,反正你的基礎(chǔ)也打得差不多了,今天我就教你今法修士的必修課--網(wǎng)絡(luò)編程。”
一、socket和TCP/IP協(xié)議
1、1什么是socket
學習網(wǎng)絡(luò)編程,我們首先就是要理解計算機之間是如何進行通信。
socket是計算機之間進行通信的一種約定或一種方式。通過 socket 這種約定,一臺計算機可以接收其他計算機的數(shù)據(jù),也可以向其他計算機發(fā)送數(shù)據(jù)。
要理解socket,就需要理解TCP/IP協(xié)議,兩者之間的關(guān)系,就如同驛站和和馳道一般。
1、2TCP/IP協(xié)議
OSI模型:
image目前實際使用的網(wǎng)絡(luò)模型是 TCP/IP 模型,它對 OSI 模型進行了簡化。它把所有的TCP/IP系列協(xié)議歸類到四個抽象層中
應(yīng)用層:TFTP,HTTP,SNMP,F(xiàn)TP,SMTP,DNS,Telnet 等等
傳輸層:TCP,UDP
網(wǎng)絡(luò)層:IP,ICMP,OSPF,EIGRP,IGMP
數(shù)據(jù)鏈路層:SLIP,CSLIP,PPP,MTU
每一抽象層建立在低一層提供的服務(wù)上,并且為高一層提供服務(wù),看起來大概是這樣子的
image
1、3socket原理
我們平常使用網(wǎng)絡(luò)傳輸信息,是將程序產(chǎn)生的數(shù)據(jù)一層層地往下傳輸,最后傳輸?shù)交ヂ?lián)網(wǎng)中。數(shù)據(jù)每向下一層,就會通過這一層的協(xié)議進行包裝,等程序發(fā)送到網(wǎng)上,已經(jīng)像俄羅斯套娃一般多了四層包裝。
而其他的用戶接收數(shù)據(jù)包的時候,也會從網(wǎng)絡(luò)結(jié)構(gòu)層一層一層的向上傳輸,同時也一層一層地拆開包裝,最后回到應(yīng)用層,就得到了程序鎖需要的數(shù)據(jù)。
給數(shù)據(jù)加包裝的過程,實際上就是在數(shù)據(jù)的頭部增加一個標志(一個數(shù)據(jù)塊),表示數(shù)據(jù)經(jīng)過了這一層,我已經(jīng)處理過了。給數(shù)據(jù)拆包裝的過程正好相反,就是去掉數(shù)據(jù)頭部的標志,讓它逐漸現(xiàn)出原形。
兩臺計算機進行通信時,必須遵守以下原則:
- 必須是同一層次進行通信,比如,A計算機的應(yīng)用層和B計算機的傳輸層就不能通信,因為它們不在一個層次,數(shù)據(jù)的拆包會遇到問題。
- 每一層的功能都必須相同,也就是擁有完全相同的網(wǎng)絡(luò)模型。如果網(wǎng)絡(luò)模型都不同,那不就亂套了,誰都不認識誰。
- 數(shù)據(jù)只能逐層傳輸,不能躍層。
- 每一層可以使用下層提供的服務(wù),并向上層提供服務(wù)。
image我們所說的Socket在應(yīng)用層與傳輸層之間,傳輸層將底層的服務(wù)提供給socket抽象層,socket抽象層再提供給應(yīng)用層,通過這個辦法來進行數(shù)據(jù)傳遞。
“師父,這么多層級協(xié)議我們都要掌握嗎?”李小庚頭皮有點麻,上個網(wǎng)原來這么麻煩嗎?
“大多數(shù)時候你的確不需要明白。但是有的時候,當你在實戰(zhàn)中遇到由于TCP算法引起的bug時,懂點相關(guān)知識就變得非常重要了?!?/p>
“明白了。”
“那好,我繼續(xù)給你講講網(wǎng)絡(luò)連接的過程。”
二、TCP/IP結(jié)構(gòu)與三次握手、四次揮手
2、1TCP數(shù)據(jù)報結(jié)構(gòu):
image
序號:Seq(Sequence Number)序號占32位,用來標識從計算機A發(fā)送到計算機B的數(shù)據(jù)包的序號,計算機發(fā)送數(shù)據(jù)時對此進行標記。
確認號:Ack(Acknowledge Number)確認號占32位,客戶端和服務(wù)器端都可以發(fā)送,Ack = Seq + 1。
標志位:每個標志位占用1Bit,共有6個,分別為URG、ACK、PSH、RST、SYN、FIN,具體含義如下:
- URG:緊急指針(urgent pointer)有效。
- ACK:確認序號有效。
- PSH:接收方應(yīng)該盡快將這個報文交給應(yīng)用層。
- RST:重置連接。
- SYN:建立一個新連接。
- FIN:斷開一個連接。
2、2連接的建立(三次握手)
使用 connect() 建立連接時,客戶端和服務(wù)器端會相互發(fā)送三個數(shù)據(jù)包
image客戶端調(diào)用socket() 函數(shù)創(chuàng)建套接字后,因為沒有建立連接,所以套接字處于CLOSED狀態(tài);服務(wù)器端調(diào)用 listen()函數(shù)后,套接字進入LISTEN狀態(tài),開始監(jiān)聽客戶端請求。
這個時候,客戶端開始發(fā)起請求:
- 當客戶端調(diào)用 connect() 函數(shù)后,TCP協(xié)議會組建一個數(shù)據(jù)包,并設(shè)置 SYN 標志位,表示該數(shù)據(jù)包是用來建立同步連接的。同時生成一個隨機數(shù)字 1000,填充“序號(Seq)”字段,表示該數(shù)據(jù)包的序號。完成這些工作,開始向服務(wù)器端發(fā)送數(shù)據(jù)包,客戶端就進入了SYN-SEND狀態(tài)。
服務(wù)器端收到數(shù)據(jù)包,檢測到已經(jīng)設(shè)置了 SYN 標志位,就知道這是客戶端發(fā)來的建立連接的“請求包”。服務(wù)器端也會組建一個數(shù)據(jù)包,并設(shè)置 SYN 和 ACK 標志位,SYN 表示該數(shù)據(jù)包用來建立連接,ACK 用來確認收到了剛才客戶端發(fā)送的數(shù)據(jù)包。
服務(wù)器生成一個隨機數(shù) 2000,填充“序號(Seq)”字段。2000 和客戶端數(shù)據(jù)包沒有關(guān)系。
服務(wù)器將客戶端數(shù)據(jù)包序號1000+1,得到1001,并用這個數(shù)字填充“確認號(Ack)”字段。
服務(wù)器將數(shù)據(jù)包發(fā)出,進入SYN-RECV狀態(tài)。
客戶端收到數(shù)據(jù)包,檢測到已經(jīng)設(shè)置了 SYN 和 ACK 標志位,就知道這是服務(wù)器發(fā)來的“確認包”。客戶端會檢測“確認號(Ack)”字段,看它的值是否為 1000+1,如果是就說明連接建立成功。
接下來,客戶端會繼續(xù)組建數(shù)據(jù)包,并設(shè)置 ACK標志位,表示客戶端正確接收了服務(wù)器發(fā)來的“確認包”。同時,將剛才服務(wù)器發(fā)來的數(shù)據(jù)包
序號2000+1,得到 2001,并用這個數(shù)字來填充“確認號(Ack)”字段。客戶端將數(shù)據(jù)包發(fā)出,進入ESTABLISED狀態(tài),表示連接已經(jīng)成功建立。
服務(wù)器端收到數(shù)據(jù)包,檢測到已經(jīng)設(shè)置了 ACK 標志位,就知道這是客戶端發(fā)來的“確認包”。服務(wù)器會檢測“確認號(Ack)”字段,看它的值是否為 2000+1,如果是就說明連接建立成功,服務(wù)器進入ESTABLISED狀態(tài)。
至此,客戶端和服務(wù)器都進入了ESTABLISED狀態(tài),連接建立成功,接下來就可以收發(fā)數(shù)據(jù)了。
三次握手的關(guān)鍵是要確認對方收到了自己的數(shù)據(jù)包,這個目標就是通過“確認號(Ack)”字段實現(xiàn)的。計算機會記錄下自己發(fā)送的數(shù)據(jù)包序號 Seq,待收到對方的數(shù)據(jù)包后,檢測“確認號(Ack)”字段,看Ack = Seq + 1是否成立,如果成立說明對方正確收到了自己的數(shù)據(jù)包。
2、3連接的斷開(四次揮手)
image建立連接后,客戶端和服務(wù)器都處于ESTABLISED狀態(tài)。這時,客戶端發(fā)起斷開連接的請求:
- 客戶端調(diào)用close() 函數(shù)后,向服務(wù)器發(fā)送 FIN 數(shù)據(jù)包,進入FIN_WAIT_1狀態(tài)。FIN 是 Finish 的縮寫,表示完成任務(wù)需要斷開連接。
- 服務(wù)器收到數(shù)據(jù)包后,檢測到設(shè)置了 FIN 標志位,知道要斷開連接,于是向客戶端發(fā)送“確認包”,進入CLOSE_WAIT狀態(tài)。
注意:服務(wù)器收到請求后并不是立即斷開連接,而是先向客戶端發(fā)送“確認包”,告訴它我知道了,我需要準備一下才能斷開連接。
- 客戶端收到“確認包”后進入FIN_WAIT_2狀態(tài),等待服務(wù)器準備完畢后再次發(fā)送數(shù)據(jù)包。
- 等待片刻后,服務(wù)器準備完畢,可以斷開連接,于是再主動向客戶端發(fā)送 FIN 包,告訴它我準備好了,斷開連接吧。然后進入LAST_ACK狀態(tài)。
- 客戶端收到服務(wù)器的 FIN 包后,再向服務(wù)器發(fā)送 ACK 包,告訴它你斷開連接吧。然后進入TIME_WAIT狀態(tài)。
- 服務(wù)器收到客戶端的 ACK 包后,就斷開連接,關(guān)閉套接字,進入CLOSED狀態(tài)。
客戶端最后一次發(fā)送 ACK包后進入 TIME_WAIT 狀態(tài),而不是直接進入 CLOSED 狀態(tài)關(guān)閉連接,這是為什么呢?
TCP 是面向連接的傳輸方式,必須保證數(shù)據(jù)能夠正確到達目標機器,不能丟失或出錯,而網(wǎng)絡(luò)是不穩(wěn)定的,隨時可能會毀壞數(shù)據(jù),所以機器A每次向機器B發(fā)送數(shù)據(jù)包后,都要求機器B”確認“,回傳ACK包,告訴機器A我收到了,這樣機器A才能知道數(shù)據(jù)傳送成功了。如果機器B沒有回傳ACK包,機器A會重新發(fā)送,直到機器B回傳ACK包。
客戶端最后一次向服務(wù)器回傳ACK包時,有可能會因為網(wǎng)絡(luò)問題導致服務(wù)器收不到,服務(wù)器會再次發(fā)送 FIN 包,如果這時客戶端完全關(guān)閉了連接,那么服務(wù)器無論如何也收不到ACK包了,所以客戶端需要等待片刻、確認對方收到ACK包后才能進入CLOSED狀態(tài)。
“怎么樣,要不是試著接觸一下不一樣的世界?”云小霄的聲音,就像是古神的低語一般,不斷地刺激著李小庚的神經(jīng)。穿越前作為一個宅男,李小庚又如何不想連上這個聽起來就是完全體元宇宙的東西呢?
李小庚深吸了一口氣,按照云小霄的指引,緩慢的運轉(zhuǎn)法力在體內(nèi)構(gòu)建出TCP/IP系列的四層架構(gòu)并且嘗試與已經(jīng)被拓印在整個世界之上的萬維仙網(wǎng)進行握手。在萬維仙網(wǎng)創(chuàng)建之初,萬法仙門的歷代先賢就已經(jīng)將架構(gòu)的具體參數(shù)記錄在了《Java真經(jīng)》內(nèi),所以李小庚很順利的就連接成功。
“萬維仙網(wǎng)主要分為兩部分,供給給所有人的萬維網(wǎng),與每個宗門、個人自己搭建的內(nèi)網(wǎng),此外還有游離在兩者之間的暗網(wǎng)。目前你還沒有繳網(wǎng)費,所以還無法連接到萬維網(wǎng),不過我們?nèi)f法仙門的內(nèi)網(wǎng)也不差,還有綠壩娘的守護,就算你這種小白也不會因為瀏覽不良網(wǎng)頁而受到邪修的侵害”說道不良網(wǎng)頁的時候,云小霄突然嘿嘿嘿的笑了起來,一看就是長期從事鑒別工作的大能。
“師父,那我也可以在萬維仙網(wǎng)建立自己的空間嗎?”
“當然,你可以用自己的云中洞天作為服務(wù)器搭建網(wǎng)站,不過嘛,這樣的私人網(wǎng)站是不被萬維仙網(wǎng)認可的?!?/p>
“那怎么樣才能被認可呢?”
云小霄狡黠的笑了笑,右手做了一個搓手指的動作:“你懂得,當然是交錢啦!你要找萬維仙網(wǎng)的各大理事宗門交一筆贊助費,然后就能獲得唯一的SSL證書認證,這個時候,你的網(wǎng)站就是一個安全的網(wǎng)站了?!?/p>
三、HTTPS和HTTP
3、1介紹
超文本傳輸協(xié)議HTTP協(xié)議被用于在Web瀏覽器和網(wǎng)站服務(wù)器之間傳遞信息,HTTP協(xié)議以明文方式發(fā)送內(nèi)容,不提供任何方式的數(shù)據(jù)加密,如果攻擊者截取了Web瀏覽器和網(wǎng)站服務(wù)器之間的傳輸報文,就可以直接讀懂其中的信息。
安全套接字層超文本傳輸協(xié)議HTTPS,為了數(shù)據(jù)傳輸?shù)陌踩琀TTPS在HTTP的基礎(chǔ)上加入了SSL/TLS協(xié)議,SSL/TLS依靠證書來驗證服務(wù)器的身份,并為瀏覽器和服務(wù)器之間的通信加密。
HTTPS協(xié)議是由SSL/TLS+HTTP協(xié)議構(gòu)建的可進行加密傳輸、身份認證的網(wǎng)絡(luò)協(xié)議,要比http協(xié)議安全。
HTTPS協(xié)議的主要作用可以分為兩種:
- 一種是建立一個信息安全通道,來保證數(shù)據(jù)傳輸?shù)陌踩?/li>
- 另一種就是確認網(wǎng)站的真實性。
3、2HTTPS和HTTP的主要區(qū)別
1、https協(xié)議需要到CA申請證書,一般免費證書較少,因而需要一定費用。
2、http是超文本傳輸協(xié)議,信息是明文傳輸,https則是具有安全性的ssl/tls加密傳輸協(xié)議。
3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
4、http的連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是由SSL/TLS+HTTP協(xié)議構(gòu)建的可進行加密傳輸、身份認證的網(wǎng)絡(luò)協(xié)議,比http協(xié)議安全。
3、3HTTP方式與Web服務(wù)器通信
第一步:建立TCP/IP連接,客戶端與服務(wù)器通過Socket三次握手進行連接
第二步:客戶端向服務(wù)端發(fā)起HTTP請求(例如:POST/login.html http/1.1)
第三步:客戶端發(fā)送請求頭信息,請求內(nèi)容,最后會發(fā)送一空白行,表示客戶端請求完畢
第四步:服務(wù)器做出應(yīng)答,表示對于客戶端請求的應(yīng)答,例如:HTTP/1.1 200 OK
第五步:服務(wù)器向客戶端發(fā)送應(yīng)答頭信息
第六步:服務(wù)器向客戶端發(fā)送請求頭信息后,也會發(fā)送一空白行,表示應(yīng)答頭信息發(fā)送完畢,接著就以Content-type要求的數(shù)據(jù)格式發(fā)送數(shù)據(jù)給客戶端
第七步:服務(wù)端關(guān)閉TCP連接,如果服務(wù)器或者客戶端增Connection:keep-alive就表示客戶端與服務(wù)器端繼續(xù)保存連接,在下次請求時可以繼續(xù)使用這次的連接
3、4HTTPS方式與Web服務(wù)器通信
image第一步:客戶使用https的URL訪問Web服務(wù)器,要求與Web服務(wù)器建立SSL連接。
第二步:Web服務(wù)器收到客戶端請求后,會將網(wǎng)站的證書信息(證書中包含公鑰)傳送一份給客戶端。
第三步:客戶端的瀏覽器與Web服務(wù)器開始協(xié)商SSL/TLS連接的安全等級,也就是信息加密的等級。
第四步:客戶端的瀏覽器根據(jù)雙方同意的安全等級,建立會話密鑰,然后利用網(wǎng)站的公鑰將會話密鑰加密,并傳送給網(wǎng)站。
第五步:Web服務(wù)器利用自己的私鑰解密出會話密鑰。
第六步:Web服務(wù)器利用會話密鑰加密與客戶端之間的通信。
四、TCP與UDP
講了HTTP和HTTPS,順便再和大家一起回憶一下TCP與UDP。
TCP 是面向連接的傳輸協(xié)議,建立連接時要經(jīng)過三次握手,斷開連接時要經(jīng)過四次握手,中間傳輸數(shù)據(jù)時也要回復 ACK 包確認,多種機制保證了數(shù)據(jù)能夠正確到達,不會丟失或出錯。
UDP 是非連接的傳輸協(xié)議,沒有建立連接和斷開連接的過程,它只是簡單地把數(shù)據(jù)丟到網(wǎng)絡(luò)中,也不需要 ACK 包確認。
如果只考慮可靠性,TCP 的確比 UDP 好。
但 UDP 在結(jié)構(gòu)上比 TCP 更加簡潔,不會發(fā)送 ACK 的應(yīng)答消息,也不會給數(shù)據(jù)包分配 Seq 序號,所以 UDP 的傳輸效率有時會比 TCP 高出很多,編程中實現(xiàn) UDP 也比 TCP 簡單。
UDP 的可靠性雖然比不上TCP,但也不會像想象中那么頻繁地發(fā)生數(shù)據(jù)損毀,在更加重視傳輸效率而非可靠性的情況下,UDP 是一種很好的選擇。比如視頻通信或音頻通信,就非常適合采用 UDP 協(xié)議。通信時數(shù)據(jù)必須高效傳輸才不會產(chǎn)生“卡頓”現(xiàn)象,用戶體驗才更加流暢,如果丟失幾個數(shù)據(jù)包,視頻畫面可能會出現(xiàn)“雪花”,音頻可能會夾帶一些雜音,這些都是無妨的。
與 UDP 相比,TCP 的生命在于流控制,這保證了數(shù)據(jù)傳輸?shù)恼_性。
TCP 的速度無法超越 UDP,但在收發(fā)某些類型的數(shù)據(jù)時有可能接近 UDP。例如,每次交換的數(shù)據(jù)量越大,TCP 的傳輸速率就越接近于 UDP。
暫時沒有建立網(wǎng)站打算的李小庚隨著云小霄一起進入了萬維仙網(wǎng),在連入的一瞬間,眼前仿佛同時有兩個世界一樣,意識也仿佛一分為二,且并沒有任何不適感。
“同時身處兩個世界的感覺是不是很神奇?”云小霄拍了拍李小庚的肩膀,感嘆道:“如果有一天你也到了那個境界,或許能創(chuàng)造出更神奇的東西吧,今法與古修最大的區(qū)別就是,今法所做的一切都是為了看到更多的風景,所以大家會聯(lián)合起來,雖然偶有爭斗,但是目標卻是一致的。而古修們則全是為了飛升不擇手段之人,他們雖然也有像我們一樣的宗門、師徒的關(guān)系紐帶,但是個人利益卻高于一切?!?/p>
“那么現(xiàn)在世界上還有古修嗎?現(xiàn)如今不都是修習今法之人嗎?”
“古修之古不在于功法,而在于內(nèi)心?!?/p>