基于node的tcp客戶端和服務端的簡單通信
1.簡單介紹下TCP/IP
TCP/IP是互聯(lián)網(wǎng)相關協(xié)議的集合,分為以下四層:應用層、傳輸層、網(wǎng)絡層、數(shù)據(jù)鏈路層。
分成四層的好處是,假如只有一層,某個地方需要改變設計時,就必須把所有整體替換掉,而分層之后只需把變動的層替換掉即可。
2. 服務端編程
node提供了net模塊來實現(xiàn)tcp編程。主要分為服務端編程和客戶端編程兩部分,先來寫服務端的:
監(jiān)聽客戶端連接
先引入net模塊,再通過net.createServer 創(chuàng)建一個TCP服務器,服務器可以監(jiān)聽一個connection事件。
net.createServer([options][, connectionListener])
options
<Object>allowHalfOpen
<boolean> 表明是否允許半開的 TCP 連接。默認值:false
。pauseOnConnect
<boolean> 表明是否應在傳入連接上暫停套接字。默認值:false
。
connectionListener
<Function> 自動設置為'connection'
事件的監(jiān)聽器
我們先不傳參數(shù):
var net = require('net'); //創(chuàng)建tcp服務器 var server = net.createServer(); //監(jiān)聽connect事件 server.on('connection', (socket) => { socket.on('data',(data)=>{ console.log(data.toString(), 'data') }) }) //設置監(jiān)聽端口 server.listen(8989); //設置監(jiān)聽時的回調函數(shù) server.on('listening', (res)=>{ console.log('in listen...') })
connection事件當有數(shù)據(jù)發(fā)送過來時會被觸發(fā)。監(jiān)聽函數(shù)的參數(shù)是一個socket,用戶可以使用它與客戶端進行交互。
通過socket的data事件可以打印出發(fā)送過來的數(shù)據(jù),在瀏覽器中打開 http://localhost:8989,瀏覽器會將請求頭的信息發(fā)送到server,所以輸出結果如下:
上面代碼中,connection事件可以傳入到createServer中,listen和listening可以合并,寫成下面這種形式:
//第二種寫法 var net = require('net'); //創(chuàng)建tcp服務器 var server = net.createServer((socket) => { socket.on('data', (data) => { console.log(data.toString(), 'data..') }) }); //設置監(jiān)聽端口 server.listen(8989, (res) => { console.log('in listen...') });
除了listening和connect事件外,server還有如下事件:
- close:TCP服務器關閉的時候觸發(fā),回調函數(shù)沒有參數(shù)
- error:TCP服務器發(fā)生錯誤的時候觸發(fā),回調函數(shù)的參數(shù)為error對象
接收數(shù)據(jù)和發(fā)送數(shù)據(jù)
通過socket的data事件接收數(shù)據(jù),write方法發(fā)送數(shù)據(jù)
socket.write(data[, encoding][, callback])
//創(chuàng)建一個TCP服務器 var server = net.createServer((socket) => { //'connect'事件的回調函數(shù) console.log('客戶端已連接'); socket.on('end', () => { console.log('客戶端已斷開'); }) //接收來自客戶端的數(shù)據(jù) socket.on('data', (data) => { console.log(data.toString(), 'data'); var readSize = socket.bytesRead; console.log('the size of data is ' + readSize); }) //向客戶端寫入數(shù)據(jù) socket.write('hello\r\n'); //設置連接最大數(shù)量,可不設 server.maxConnection = 3; server.getConnections(function (err, count) { console.log('the count of clieent is ' + count); }); }) server.listen(8989, () => { console.log('服務器已啟動'); //獲取地址信息 var address = server.address(); //獲取地址端口 console.log('the port of server is ' + address.port); console.log('the address of server is ' + address.address); console.log('the ip family of server is ' + address.family); })
我們先不寫客戶端的代碼,先用telnet工具來當作客戶端來測試上面代碼
打開命令行工具輸入 telnet localhost 8989
可以看到socket.write('hello\r\n')這句話已經(jīng)生效了,服務端向客戶端返回了hello,但這樣肯定還不夠,
3. 客戶端編程
客戶端編程比服務端簡單,因為不用監(jiān)聽端口。只要把數(shù)據(jù)從指定的端口發(fā)出去就可以了。
net.createConnection(options[, connectListener]) 用來創(chuàng)建一個socket。第一個參數(shù)必填,要寫發(fā)送的端口號,第二個參數(shù)是這個socket的'connect'事件的回調函數(shù)
//創(chuàng)建一個客戶端 var client = net.connect({ port: 8989 }, () => { console.log('連接到服務器'); //向服務端發(fā)送數(shù)據(jù) client.write('hello,i am from client'); }) //監(jiān)聽事件,當服務端發(fā)送數(shù)據(jù)過來時會觸發(fā)該事件 client.on('data', (data) => { console.log(data, 'data'); client.end() }) client.on('end', () => { console.log('已從服務器斷開'); });
上面代碼的client就是一個socket,所以可以監(jiān)聽data事件來獲取服務端發(fā)送來的數(shù)據(jù)。然后socket也可以通過write來向服務端發(fā)送數(shù)據(jù)
4. 一個小的登錄系統(tǒng)
利用上面的知識,可以實現(xiàn)一個小型的登錄系統(tǒng):
/*server.js*/ var net = require('net'); //這兒用一個對象來模擬數(shù)據(jù)庫,保存用戶名和密碼 var user = { admin: '123', test: '333', lucy: '222', } //臨時變量保存用戶輸入的內(nèi)容 var username = ''; var server = net.createServer((socket)=>{ console.log('服務器已連接'); socket.write('請輸入用戶名:'); socket.on('data',(data)=>{ //通過stdin輸入的內(nèi)容是buffer,需要轉成字符串且清除空格 data = data.toString().trim(); if(!username){ if(user[data]){ socket.write('請輸入密碼:'); username = data; }else{ socket.write('用戶名不對,請輸入用戶名:'); } }else { if(user[username] === data){ socket.write('登錄成功'); }else { socket.write('密碼不對,請輸入密碼:'); } } }); socket.on('close',data=>{ console.log(data); }) }) server.listen(8899,()=>{ console.log('服務器監(jiān)聽8899端口中') })
到此這篇關于基于node的tcp客戶端和服務端的簡單通信的文章就介紹到這了,更多相關基于node的tcp客戶端和服務端的簡單通信內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
node的process以及child_process模塊學習筆記
這篇文章主要介紹了node的process以及child_process模塊學習筆記,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03手寫簡版無三方依賴的Node-Server實現(xiàn)示例
這篇文章主要為大家介紹了手寫簡版無三方依賴的Node-Server實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06