對於初學者,或者沒有接觸過網絡編程的程序員,會以爲網絡編程涉及的知識很高深,很難,其實這是一種誤解,當你的語法熟悉之後,其實基本的網絡編程如今已經被實現的異常簡單了。javascript
網絡通訊做爲互聯網的技術支持,已被普遍應用在軟件開發中,不管是Web,服務端,客戶端仍是桌面應用,都是必須掌握的一門技術。前端
網絡編程是什麼?java
在軟件開發層面實現遠程數據交換的編程技術。網絡編程的本質是兩個設備之間的數據交換,固然,在計算機網絡中,設備主要指計算機。數據傳遞自己沒有多大的難度,不就是把一個設備中的數據發送給另一個設備,而後接受另一個設備反饋的數據。程序員
OSI參考模型web
OSI參考模型,也能夠叫作OSI七層模型,在學習網絡編程的時候,都會接觸到OSI七層模型
,咱們通常使用的網絡數據傳輸由下而上分爲七層,這是一個理論的模型。分別是物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層、應用層
。以下表所示:面試
層數 | 名稱 | 描述 |
---|---|---|
第七層 | 應用層 | 應用層是 OSI 參考模型的最高層,負責爲用戶的應用程序提供網絡服務。與 OSI 其餘層不一樣的是,它不爲任何其餘 OSI 層提供服務,而只是爲 OSI 模型之外的應用程序提供服務。包括爲相互通訊的應用程序或進行之間創建鏈接、進行同步,創建關於錯誤糾正和控 制數據完整性過程的協商等。應用層還包含大量的應用協議,如分佈式數據庫的訪問、文件的交換、電子郵件、虛擬終端等。 |
第六層 | 表示層 | 表示層如下的各層只關心可靠的數據傳輸,而表示層關心的是所傳輸數據的語法和語義。它主要涉及處理在兩個通訊系統之間所交換信息的表示方式,包括數據格式變換、數據加密與解密、數據壓縮與恢復等功能。 |
第五層 | 會話層 | 會話層的功能是在兩個節點間創建、維護和釋放面向用戶的鏈接。它是在傳輸鏈接的基礎上創建會話鏈接,並進行數據交換管理,容許數據進行單工、半雙工和全雙工的傳送。會話層提供了令牌管理和同步兩種服務功能。 |
第四層 | 傳輸層 | 傳輸層是OSI七層模型中惟一負責端到端節點間數據傳輸和控制功能的層。傳輸層是OSI七層模型中承上啓下的層,它下面的三層主要面向網絡通訊,以確保信息被準確有效地傳輸;它上面的三個層次則面向用戶主機,爲用戶提供各類服務。傳輸層經過彌補網絡層服務質量的不足,爲會話層提供端到端的可靠數據傳輸服務。它爲會話層屏蔽了傳輸層如下的數據通訊的細節,使會話層不會受到下三層技術變化的影響。但同時,它又依靠下面的三個層次控制實際的網絡通訊操做,來完成數據從源到目標的傳輸。傳輸層爲了向會話層提供可靠的端到端傳輸服務,也使用了差錯控制和流量控制等機制。 |
第三層 | 網絡層 | 網絡中的兩臺計算機進行通訊時,中間可能要通過許多中間結點甚至不一樣的通訊子網。 網絡層的任務就是在通訊子網中選擇一條合適的路徑,使發送端傳輸層所傳下來的數據能 夠經過所選擇的路徑到達目的端。網絡層必須使用尋址方案來肯定存在哪些網絡以及設備在這些網絡中所處的位置,不一樣網絡層協議所採用的尋址方案是不一樣的。在肯定了目標結點的位置後, 網絡層還要負責引導數據包正確地經過網絡,找到經過網絡的最優路徑,即路由選擇。若是子網中同時出現過多的分組,它們將相互阻塞通路並可能造成網絡瓶頸,因此網絡層還須要提供擁塞控制機制以免此類現象的出現。 |
第二層 | 數據鏈路層 | 數據鏈路層涉及相鄰節點之間的可靠數據傳輸,數據鏈路層經過增強物理層傳輸原始比特的功能,使之對網絡層表現爲一條無錯線路。爲了可以實現相鄰節點之間無差錯的數據傳送,數據鏈路層在數據傳輸過程當中提供了確認、差錯控制和流量控制等機制。 |
第一層 | 物理層 | 物理層位於OSI參考模型的最低層,它直接面向原始比特流的傳輸。爲了實現原始比特流的物理傳輸,物理層必須解決好包括傳輸介質、信道類型、數據與信號之間的轉換、信號傳輸中的衰減和噪聲等在內的一系列問題。另外,物理層標準要給出關於物理接口的機械、 電氣、功能和規程特性,以便於不一樣的製造廠家既可以根據公認的標準各自獨立地製造設備,又能使各個廠家的產品可以相互兼容。 |
爲何OSI要採用分層的形式?由於一個軟件邏輯的實現,就是對其進行分層處理。最熟悉不過的就是MVC
,如把後臺的代碼會分爲,數據層,表現層,業務邏輯層,還有如今的先後臺分離這種,其實都是分層的一種表現形式,讓每一部分的工做都變的跟加的精確和具體。數據庫
可是在項目中不會像IOS參考模型中那樣分層那麼細緻,比較經常使用的可能就是TCP/IP
協議,那麼說到這,什麼又是TCP/IP
協議:編程
TCP/IP
提供點對點的連接機制,將數據應該如何封裝、定址、傳輸、路由以及在目的地如何接收,都加以標準化。它將軟件通訊過程抽象化爲四個抽象層,採起協議堆棧的方式,分別實現出不一樣通訊協議。協議族下的各類協議,依其功能不一樣,被分別歸屬到這四個層次結構之中,常被視爲是簡化的七層OSI模型
。瀏覽器
層數 | 名稱 | 涵蓋協議 |
---|---|---|
第四層 | 應用層 | TELNET/SSH/HTTP/SMTP/POP/MIB/SIP/HTML(超文本傳輸協議)... |
第三層 | 傳輸層 | TCP/UDP/SCTP/DCCP... |
第二層 | 網際層 | ARP/IPv4/ICMP... |
第一層 | 物理層 | 以太網/無線LAN/PPP... |
經過上表中能夠看出各個層級所包含的協議,能夠把第一層和第二層看做爲底層協議,然而在編寫軟件過程當中不多的時候會用到這兩層,由於這輛層通常用到會涉及到物理設備,例如鏈路、無線這些東西,不多會涉及到軟件的邏輯。第三層是在軟件開發過程當中比較經常使用的,好比TCP,UDP以後會詳細介紹。應用層會更加的熟悉,在作遠程登陸,數據傳輸時會頻繁的使用到。緩存
DNS解析
DNS
解析的過程就是尋找哪臺機器上有你須要資源的過程。當你在瀏覽器中輸入一個地址時,例如www.google.com
,其實不是百度網站真正意義上的地址。互聯網上每一臺計算機的惟一標識是它的IP
地址,可是IP
地址並不方便記憶。用戶更喜歡用方便記憶的網址去尋找互聯網上的其它計算機,也就是上面提到的百度的網址。因此互聯網設計者須要在用戶的方便性與可用性方面作一個權衡,這個權衡就是一個網址到IP地址的轉換,這個過程就是DNS
解析。它實際上充當了一個翻譯的角色,實現了網址到IP
地址的轉換。網址到IP
地址轉換的過程是如何進行的?
首先在本地域名服務器中查詢IP
地址,若是沒有找到的狀況下,本地域名服務器會向根域名服務器發送一個請求,若是根域名服務器也不存在該域名時,本地域名會向com
頂級域名服務器發送一個請求,依次類推下去。直到最後本地域名服務器獲得google
的IP
地址並把它緩存到本地,供下次查詢使用。從上述過程當中,能夠看出網址的解析是一個從右向左的過程:com -> google.com -> www.google.com
。可是你是否發現少了點什麼,根域名服務器的解析過程呢?事實上,真正的網址是www.google.com
.,並非我多打了一個.,這個.對應的就是根域名服務器,默認狀況下全部的網址的最後一位都是.,既然是默認狀況下,爲了方便用戶,一般都會省略,瀏覽器在請求DNS的時候會自動加上,全部網址真正的解析過程爲:. -> .com -> google.com. -> www.google.com
。
TCP鏈接
HTTP
協議是使用TCP
做爲其傳輸層協議的,當TCP
出現瓶頸時,HTTP
也會受到影響。我不知道把HTTPS
放在這個部分是否合適,可是放在這裏好像又說的過去。HTTP
報文是包裹在TCP
報文中發送的,服務器端收到TCP
報文時會解包提取出HTTP
報文。可是這個過程當中存在必定的風險,HTTP
報文是明文,若是中間被截取的話會存在一些信息泄露的風險。那麼在進入TCP
報文以前對HTTP
作一次加密就能夠解決這個問題了。HTTPS
協議的本質就是HTTP+SSL(orTLS)
。在HTTP
報文進入TCP
報文以前,先使用SSL
對HTTP
報文進行加密。從網絡的層級結構看它位於HTTP
協議與TCP
協議之間。
原理:Net模塊提供一個異步API可以建立基於流的TCP服務器,客戶端與服務端簡歷鏈接後,服務器能夠得到一個全雙工Socket對象,服務器能夠保存Socket對象列表,在接收某客戶端消息時,推送給客戶端。
dome
服務端:
const net = require("net"); const chatServer = net.createServer(); const clientList = []; chatServer.on("connection",client => { client.write("Hi!\n"); clientList.push(client); client.on("data",data => { console.log("receive:",data.toString()); clientList.forEach(v => { v.write(data); }) }) }); chatServer.listen(9000);
TCP特性
TCP並不能保證數據必定會被對方接收到,由於這是不可能的。TCP可以作到的是,若是有可能,就把數據遞送到接收方,不然就(經過放棄重傳而且中斷鏈接這一手段)通知用戶。所以準確說 TCP 也不是 100% 可靠的協議,它所能提供的是數據的可靠遞送或故障的可靠通知。
三次握手與四次揮手
所謂三次握手(Three-way Handshake
),是指創建一個TCP
鏈接時,須要客戶端和服務器總共發送3個包。
三次握手的目的是鏈接服務器指定端口,創建TCP
鏈接,並同步鏈接雙方的序列號和確認號,交換 TCP 窗口大小信息。在socket
編程中,客戶端執行connect()
時。將觸發三次握手。
狀態 | 描述 |
---|---|
第一次握手 | 客戶端發送一個TCP 的SYN 標誌位置1的包,指明客戶端打算鏈接的服務器的端口,以及初始序號X ,保存在包頭的序列號(Sequence Number )字段裏。 |
第二次握手 | 服務器發回確認包(ACK )應答。即SYN 標誌位和ACK 標誌位均爲1。服務器端選擇本身ISN 序列號,放到Seq 域裏,同時將確認序號(Acknowledgement Number )設置爲客戶的ISN 加1,即X+1 。 發送完畢後,服務器端進入SYN_RCVD 狀態。 |
第三次握手 | 客戶端再次發送確認包(ACK ),SYN 標誌位爲0,ACK 標誌位爲1,而且把服務器發來ACK 的序號字段+1,放在肯定字段中發送給對方,而且在數據段放寫ISN 的+1。 |
TCP 的鏈接的拆除須要發送四個包,所以稱爲四次揮手(Four-way handshake
),也叫作改進的三次握手。客戶端或服務器都可主動發起揮手動做,在socket
編程中,任何一方執行close()
操做便可產生揮手操做。
狀態 | 描述 |
---|---|
第一次揮手 | 假設客戶端想要關閉鏈接,客戶端發送一個FIN 標誌位置爲1的包,表示本身已經沒有數據能夠發送了,可是仍然能夠接受數據。發送完畢後,客戶端進入FIN_WAIT_1 狀態。 |
第二次揮手 | 服務器端確認客戶端的FIN 包,發送一個確認包,代表本身接受到了客戶端關閉鏈接的請求,但尚未準備好關閉鏈接。發送完畢後,服務器端進入CLOSE_WAIT 狀態,客戶端接收到這個確認包以後,進入FIN_WAIT_2 狀態,等待服務器端關閉鏈接。 |
第三次揮手 | 服務器端準備好關閉鏈接時,向客戶端發送結束鏈接請求,FIN 置爲1。發送完畢後,服務器端進入LAST_ACK 狀態,等待來自客戶端的最後一個ACK 。 |
第四次揮手 | 客戶端接收到來自服務器端的關閉請求,發送一個確認包,並進入TIME_WAIT 狀態,等待可能出現的要求重傳的ACK 包。服務器端接收到這個確認包以後,關閉鏈接,進入CLOSED 狀態。客戶端等待了某個固定時間以後,沒有收到服務器端的ACK ,認爲服務器端已經正常關閉鏈接,因而本身也關閉鏈接,進入CLOSED 狀態。 |
TCP斷開鏈接時須要四次握手,爲何須要4次呢?這是因爲TCP半關閉的性質形成的。所謂半關閉,就是能夠發送數據,卻不能接收數據或只能接收數據,不能發送數據。
HTTP協議
說到這裏就是老生常談的話題了,做爲一個前端碼農來說,在面試過程當中的是時候這個問題已經被問爛了,基本每次面試都會被問到。
其實這部分又能夠稱爲前端工程師眼中的HTTP
,它主要發生在客戶端。發送HTTP
請求的過程就是構建HTTP
請求報文並經過TCP
協議中發送到服務器指定端口(HTTP協議80/8080
,HTTPS協議443
)。HTTP請求報文是由三部分組成: 請求行, 請求報頭和請求正文。
特性:
請求報文
HTTP
協議是以ASCII
碼傳輸,創建在TCP/IP
協議之上的應用層規範。規範把HTTP
請求分爲三個部分:狀態行、請求頭、消息主體。
HTTP 定義了與服務器交互的不一樣方法,最基本的方法有4種,分別是GET,POST,PUT,DELETE
。URL
全稱是資源描述符,咱們能夠這樣認爲:一個URL
地址,它用於描述一個網絡上的資源,而 HTTP
中的GET,POST,PUT,DELETE
就對應着對這個資源的查,增,改,刪4個操做。
所謂安全的意味着該操做用於獲取信息而非修改信息。換句話說,GET
請求通常不該產生反作用。就是說,它僅僅是獲取資源信息,就像數據庫查詢同樣,不會修改,增長數據,不會影響資源的狀態。
GET方法與POST方法的區別
GET | POST |
---|---|
GET重點在從服務器上獲取資源 | POST重點在向服務器發送數據 |
GET傳輸數據是經過URL請求,以field(字段)= value的形式,置於URL後,並用"?"鏈接,多個請求數據間用"&"鏈接 | POST傳輸數據經過Http的POST機制,將字段與對應值封存在請求實體中發送給服務器,這個過程對用戶是不可見的 |
GET傳輸的數據量小,由於受URL長度限制,但效率較高 | Post能夠傳輸大量數據,因此上傳文件時只能用Post方式 |
GET是不安全的,由於URL是可見的,可能會泄露私密信息,如密碼等 | POST較GET安全性較高 |
GET方式只能支持ASCII字符,向服務器傳的中文字符可能會亂碼 | POST支持標準字符集,能夠正確傳遞中文字符 |
總結
網絡編程就是使用IP地址,或域名,和端口鏈接到另外一臺計算機上對應的程序,按照規定的協議(數據格式)來交換數據,實際編程中創建鏈接和發送、接收數據在語言級已經實現,作的更多的工做是設計協議,以及編寫生成和解析數據的代碼罷了,而後把數據轉換成邏輯的結構顯示或控制邏輯便可。
對於初學者,或者沒有接觸過網絡編程的程序員,會以爲網絡編程涉及的知識很高深,很難,其實這是一種誤解,當你的語法熟悉之後,其實基本的網絡編程如今已經被實現的異常簡單了。