這篇文章主要介紹了Nodejs中的net模塊怎么用的相關知識,內(nèi)容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Nodejs中的net模塊怎么用文章都會有所收獲,下面我們一起來看看吧。
成都創(chuàng)新互聯(lián)專注于資興網(wǎng)站建設服務及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供資興營銷型網(wǎng)站建設,資興網(wǎng)站制作、資興網(wǎng)頁設計、資興網(wǎng)站官網(wǎng)定制、微信小程序服務,打造資興網(wǎng)絡公司原創(chuàng)品牌,更為您提供資興網(wǎng)站排名全網(wǎng)營銷落地服務。
想要學明白通信模塊,就不得不了解網(wǎng)絡通信模型,想要記住網(wǎng)絡通信模型,就不得不實際操作來輔助記憶. 這個是面試的重點. 這一塊內(nèi)容很多,想要跟深入的了解,還說需要體系的學習的. 這里只是簡單提提.
寄出這張老圖:
對于我們前端而言, 需要記住 TCP/IP 協(xié)議簇的體系結(jié)果既可.
應用層: http(80 端口)、FTP(21)、SMTP(發(fā)送郵件)、POP(接收郵件)、DNS
傳輸層: TCP/ UDP
網(wǎng)際層: IP,ICMP(是 IP 層的附屬協(xié)議)
數(shù)據(jù)鏈路層: PPP, SLIP
物理層: 網(wǎng)有雙絞線、同軸電纜、光纖等傳輸方式, 遵循 ISO2110 規(guī)范
從ICMP
這種依附于 IP 協(xié)議的協(xié)議可以知道,對于網(wǎng)絡協(xié)議的分層不用過于較勁. ICMP
明明需要 IP 協(xié)議為基礎,但是它也被規(guī)劃為網(wǎng)絡層. 我們對于 OSI 模型的正確的認識,我認為應該是用 OSI 模型來進行問題的分析比用來對于協(xié)議進行所謂的分層更加來得有意義.
TCP/IP 協(xié)議簇 并不是只是指 TCP 和 IP 協(xié)議,只是因為這兩個協(xié)議過于出圈,所以就用 TCP/IP 來統(tǒng)稱互聯(lián)網(wǎng)相關聯(lián)的協(xié)議集合起來. 還有另外一種說法是,在使用 TCP/IP 協(xié)議過程中使用到的協(xié)議族的統(tǒng)稱.
而客戶端和服務端的傳輸流如下
如果角色變成發(fā)送者
和接受者
的時候,傳輸流如下圖:
可以看出來傳輸?shù)倪^程中,從發(fā)送端開始,沒經(jīng)過一層協(xié)議都會加上所需要的首部信息.層層把關,層層加碼. 然后到了接收端的時候, 就反而行之, 每經(jīng)過一層都剝?nèi)氖撞? 只等到最后拿到的 HTTP 數(shù)據(jù).
上面圖片出自《圖解 HTTP》
上面就是大體的網(wǎng)絡協(xié)議模型.
疑惑: 為什么書上和很多地方在把 OSI 體系結(jié)果中合并成 TCP/IP 五層協(xié)議之后,網(wǎng)絡層的名稱會變成網(wǎng)際層呢?
第一次握手: 客戶端向服務端發(fā)送 SYN 標志位(序號是 J), 并進入 SYN_SENT 狀態(tài)(等待服務端確認狀態(tài))
第二次握手: 服務端收到來自客戶端的 SYN J, 服務端會確認該數(shù)據(jù)包已收到并發(fā)送 ACK 標志位(序號是 J + 1)和 SYN 標志位(序號是 K), 隨后進入 SYN_REVD 狀態(tài)(請求接受并等待客戶端確認狀態(tài))
第三次握手: 客戶端進入連接建立狀態(tài)后,向服務端發(fā)送 ACK 標志位(K+ 1) , 確認客戶端已收到建立連接,服務器收到 ACK 標志后,服務端進入連接已建立狀態(tài).
J 和 K 都是為了確立是誰在請求. SYN 和 ACK 的結(jié)構沒有什么不同,只是發(fā)送的對象不一樣.
net模塊
就是對于上面 TCP 連接的具體實現(xiàn).
首先, 學習 API 依舊推薦直接進入官方文檔. 其中中文文檔內(nèi)容不會是最新版本的
在學習的時候,能夠有時間看英文文檔就盡量看英文文檔. 對于這一點我堅持了半年. 從一開始看不下去,直到現(xiàn)在能夠可以忍住不舒適感看下去. 半年時間進步就很明顯了. 而且這種不舒適感是一件好事,說明這個不是你的舒適區(qū),畢竟勇于跨過自己的舒適區(qū)才是進步的源泉
接下來,進行正題.既然要學習通信,那么我們就需要兩個對象來模擬客戶端和服務端.分別建立client.js
和service.js
兩個文件. 通過命令行創(chuàng)建:
touch client.js && touch service.js
引入net
模塊,并讓服務器進入LISTENT
狀態(tài), 以及配置端口號和 HOST 地址(手動略過 DNS 解析過程), 等待客戶端的召喚
const net = require("net"); const post = 3306; const host = "127.0.0.1"; const server = net.createServer(); server.listen(post, host);
此時服務器對應了 TCP 連接中服務器LISTEN
狀態(tài).
隨后監(jiān)聽一些必要的事件,也就是 server 提供的鉤子. (屬于 event 相關知識)
server.on("listening", () => { console.log("服務器已經(jīng)可以連接啦"); }); server.on("connection", (socket) => { console.log("有客戶端來訪咯"); }); server.on("close", () => { console.log("服務器關閉了"); }); server.on("error", (error) => { console.log("服務器出錯啦: ", error); // error 有錯誤的信息 });
上面這一串代碼涉及到了,
listening
: 監(jiān)聽端口后出發(fā)的事件
connection
: 有客戶端來訪的時候觸發(fā)事件
close
: 服務器關閉觸發(fā)
error
: 服務器出錯觸發(fā)
對于close
我們需要注意的是,后臺大哥一般是直接
ps kill -9 pid
通過殺死線程的方式來進行的
在connection
狗子中, 形參是 socket 命名. 它的中文翻譯為嵌套字, 被 node 封裝成了 stream(流).在可以粗淺的理解為就是客戶端發(fā)送過來的數(shù)據(jù). 這是這個數(shù)據(jù)自身是有方法的. 我在connection
中對socket
來進行處理
server.on("connection", (socket) => { console.log("有客戶端來訪咯"); socket.on("data", (data) => { console.log(data); // 客戶端發(fā)送過來的數(shù)據(jù) }); });
stream 以后的文章會進行介紹.
服務端既然能夠接受客戶端發(fā)過來的數(shù)據(jù),自然也能夠給客戶端回復. 在socket.on
中寫入(當然也可以寫在外面):
socket.write("我已經(jīng)收到你的服務器了哦,客戶端");
此時如果客戶端已經(jīng)完成了數(shù)據(jù)的接受,然后關閉了連接.我們可以也可以通過socket.on('close‘)
鉤子監(jiān)聽到:
socket.on("close", () => { console.log("客戶端把另外一頭的流給關了"); });
對于socket
事件的總結(jié)放入client.js
中.
此時service.js
的所有內(nèi)容如下:
const net = require("net"); const post = 3306; const host = "127.0.0.1"; const server = net.createServer(); server.listen(post, host); server.on("listening", () => { console.log("服務器已經(jīng)可以連接啦"); }); server.on("connection", (socket) => { console.log("有客戶端來訪咯"); socket.on("data", (data) => { console.log(data); // 客戶端發(fā)送過來的數(shù)據(jù) socket.write("我已經(jīng)收到你的服務器了哦,客戶端"); }); socket.on("close", () => { console.log("客戶端把另外一頭的流給關了"); server.close(); // 客戶端已經(jīng)不要數(shù)據(jù)了,那么我們就把服務器給關閉了吧 }); }); server.on("close", () => { console.log("服務器關閉了"); }); server.on("error", (error) => { console.log("服務器出錯啦: ", error); // error 有錯誤的信息 });
客戶端的就簡單很多.
const net = require("net"); const post = 3306; const host = "127.0.0.1"; const socket = net.connect(post, host); socket.on("connect", () => { console.log("已經(jīng)連接到服務器了哦"); }); socket.write("服務器, 我來了"); socket.on("data", (data) => { console.log(data.toString()); socket.end(); }); socket.on("close", () => { console.log("連接已關閉了"); });
對于socket
的事件的總結(jié)
connect
: 成功和服務器連接觸發(fā)
data
: 接受到服務器發(fā)過來的參數(shù)
end
: 數(shù)據(jù)接收完畢之后可以觸發(fā)
close
: socket 關閉觸發(fā)
service.js
和client.js
框架已經(jīng)寫完, 那些先后在打開兩個終端運行他們:
node service.js node client.js
自行查看打印的結(jié)果.
整個 TCP 連接的框架大體就已經(jīng)完成了. 當然實際的生產(chǎn)遠遠不止這些. 還要處理粘包、拆包/封包, 心跳包等等.
關于“Nodejs中的net模塊怎么用”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“Nodejs中的net模塊怎么用”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道。