這篇文章給大家介紹如何使用Node.js進行TCP網絡通信,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
廣安網站建設公司成都創(chuàng)新互聯(lián),廣安網站設計制作,有大型網站制作公司豐富經驗。已為廣安近千家提供企業(yè)網站建設服務。企業(yè)網站搭建\成都外貿網站制作要多少錢,請找那個售后服務好的廣安做網站的公司定做!
摘要: 網絡是通信互聯(lián)的基礎,Node.js提供了net、http、dgram等模塊,分別用來實現(xiàn)TCP、HTTP、UDP的通信。
1.1、使用Node.js創(chuàng)建TCP服務器
為了使用Node.js創(chuàng)建TCP服務器,首先要調用require(‘net’)來加載net模塊,然后調用net模塊的createServer方法就可以輕松地創(chuàng)建一個TCP服務器,語法格式如下:
net.createServer([options][, connectionListener]) options是一個對象參數(shù)值,有兩個布爾類型的屬性allowHalfOpen和pauseOnConnect。這兩個屬性默認都是false; connectionListener是一個當客戶端與服務端建立連接時的回調函數(shù),這個回調函數(shù)以socket端口對象作為參數(shù)。
1.2、監(jiān)聽客戶端的連接
使用TCP服務器的listen方法就可以開始監(jiān)聽客戶端的連接,語法格式如下:
server.listen(port[, host][, backlog][, callback]); port:為需要監(jiān)聽的端口號,參數(shù)值為0的時候將隨機分配一個端口號; host:服務器地址; backlog:連接等待隊列的最大長度; callback:回調函數(shù)。
以下代碼可以創(chuàng)建一個TCP服務器并監(jiān)聽8001端口:
//引入net模塊 const net = require('net'); //創(chuàng)建TCP服務器 const server = net.createServer(function (socket) { console.log('有新的客戶端接入'); }); //設置監(jiān)聽端口 server.listen(8001, function () { console.log('服務正在監(jiān)聽中。。。') });
運行這段代碼,可以在控制臺看到執(zhí)行了listen方法的回調函數(shù),如圖所示:
可以使用相應的TCP客戶端或者調試工具來連接這個已經創(chuàng)建好的TCP服務器。例如,要使用Windows的Telnet就可以用以下命令來連接:
telnet localhost 8001
連接成功后可以看到控制臺打印了“有新的客戶端接入”字樣,表明createServer方法的回調函數(shù)已經執(zhí)行,說明已經成功連接到這個創(chuàng)建好的TCP服務器。
server.listen()方法其實觸發(fā)的是server下的listening事件,所以也可以手動監(jiān)聽listening事件,代碼如下:
//設置監(jiān)聽端口 server.listen(8001); //設置監(jiān)聽時的回調函數(shù) server.on('listening', function () { console.log("服務正在監(jiān)聽中。。。") });
除了listening事件外,TCP服務器還支持以下事件:
connection:當有新的鏈接創(chuàng)建時觸發(fā),回調函數(shù)的參數(shù)為socket連接對象。 close:TCP服務器關閉的時候觸發(fā),回調函數(shù)沒有參數(shù)。 error:TCP服務器發(fā)生錯誤的時候觸發(fā),回調函數(shù)的參數(shù)為error對象。
下列代碼通過net.Server類來創(chuàng)建一個TCP服務器,添加以上事件:
//引入net模塊 const net = require('net'); //實例化一個服務器對象 const server = new net.Server(); //監(jiān)聽connection事件 server.on('connection', function (socket) { console.log('有新的客戶端接入'); }); //設置監(jiān)聽端口 server.listen(8001); //設置監(jiān)聽時的回調函數(shù) server.on('listening', function () { console.log('服務正在監(jiān)聽中。。。'); }); //設置關閉時的回調函數(shù) server.on('close', function () { console.log('服務已關閉'); }); //設置出錯時的回調函數(shù) server.on('error', function (err) { console.log('服務運行異常', err); });
1.3、查看服務器監(jiān)聽的地址
當創(chuàng)建了一個TCP服務器后,可以通過server.address()方法來查看這個TCP服務器監(jiān)聽的地址,并返回一個JSON對象,因為這個方法返回的是TCP服務器監(jiān)聽的地址信息,所以應該在調用了server.listen()方法或者綁定了事件listening中的回調函數(shù)中調用該方法。這個對象的屬性有:
port:TCP服務器監(jiān)聽的端口號; family:說明TCP服務器監(jiān)聽的地址是IPv6還是IPv4; address:TCP服務器監(jiān)聽的地址。
代碼如下:
//引入net模塊 const net = require('net'); //創(chuàng)建TCP服務器 const server = net.createServer(function (socket) { console.log('有新的客戶端接入'); }); //設置監(jiān)聽端口 server.listen(8001); //設置監(jiān)聽時的回調函數(shù) server.on('listening', function () { //獲取地址信息 let address = server.address(); //獲取地址詳細信息 console.log("服務器監(jiān)聽的端口是:" + address.port); console.log("服務器監(jiān)聽的地址是:" + address.address); console.log("服務器監(jiān)聽的地址類型是:" + address.family); });
運行結果如圖:
1.4、連接服務器的客戶端數(shù)量
創(chuàng)建一個TCP服務器后,可以通過server.getConnections()方法獲取連接這個TCP服務器的客戶端數(shù)量。這個方法是一個異步的方法,回調函數(shù)有兩個參數(shù):
第一個參數(shù)為error對象。 第二個參數(shù)為連接TCP服務器的客戶端數(shù)量。
除了獲取連接數(shù)外,也可以通過設置TCP服務器的maxConnections屬性來設置這個TCP服務器的最大連接數(shù)。當連接數(shù)超過最大連接數(shù)的時候,服務器將拒絕新的連接。如下代碼設置這個TCP服務器的最大連接數(shù)為3。
//引入net模塊 const net = require('net'); //創(chuàng)建TCP服務器 const server = net.createServer(function (socket) { console.log('有新的客戶端接入'); //設置最大連接數(shù)量 server.maxConnections = 3; server.getConnections(function (err, count) { console.log("當前連接的客戶端個數(shù)為:" + count); }); }); //設置監(jiān)聽端口 server.listen(8001, function () { console.log("服務正在監(jiān)聽中。。。") });
運行這段代碼,并嘗試用多個客戶端連接。可以發(fā)現(xiàn)當客戶端連接數(shù)超過3的時候,新的客戶端就無法連接這個服務器了,如圖所示:
1.5、獲取客戶端發(fā)送的數(shù)據(jù)
createServer方法的回調函數(shù)參數(shù)是一個net.Socket對象(服務器所監(jiān)聽的端口對象),這個對象同樣也有一個address()方法,用來獲取TCP服務器綁定的地址,同樣也是返回一個含有port、family、address屬性的對象。通過socket對象可以獲取客戶端發(fā)送的流數(shù)據(jù),每次接收到數(shù)據(jù)的時候觸發(fā)data事件,通過監(jiān)聽這個事件就可以在回調函數(shù)中獲取客戶端發(fā)送的數(shù)據(jù),代碼如下:
//引入net模塊 const net = require('net'); //創(chuàng)建TCP服務器 const server = net.createServer(function (socket) { //監(jiān)聽data事件 socket.on("data", function (data) { //打印數(shù)據(jù) console.log("接收到數(shù)據(jù):" + data.toString()); }); }); //設置監(jiān)聽端口 server.listen(8001, function () { console.log("服務正在監(jiān)聽中。。。") });
測試結果如下:
socket對象除了有data事件外,還有connect、end、error、timeout等事件。
1.6、發(fā)送數(shù)據(jù)給客戶端
調用socket.write()可以使TCP服務器發(fā)送數(shù)據(jù),這個方法只有一個必需參數(shù),就是需要發(fā)送的數(shù)據(jù);第二個參數(shù)為編碼格式,可選。同時,可以為這個方法設置一個回調函數(shù)。當有用戶連接TCP服務器的時候,將發(fā)送數(shù)據(jù)給客戶端,代碼如下:
//引入net模塊 const net = require('net'); //創(chuàng)建TCP服務器 const server = net.createServer(function (socket) { //設置消息內容 const message = "Hello Client......"; //發(fā)送數(shù)據(jù) socket.write(message, function () { const writeSize = socket.bytesWritten; console.log("數(shù)據(jù)發(fā)送成功,數(shù)據(jù)長度為:" + writeSize); }); //監(jiān)聽data事件 socket.on("data", function (data) { const readSize = socket.bytesRead; //打印數(shù)據(jù) console.log("接收到數(shù)據(jù)為:" + data.toString(), ";接收的數(shù)據(jù)長度為:" + readSize); }); }); //設置監(jiān)聽端口 server.listen(8001, function () { console.log("服務正在監(jiān)聽中。。。") });
測試結果如下:
在上面這段代碼中還用到了socket對象的bytesWritten和bytesRead屬性,這兩個屬性分別代表著發(fā)送數(shù)據(jù)的字節(jié)數(shù)和接收數(shù)據(jù)的字節(jié)數(shù)。除了上面這兩個屬性外,socket對象還有以下屬性:
socket.localPort:本地端口的地址; socket.localAddress:本地IP地址; socket.remotePort:進程端口地址; socket.remoteFamily:進程IP協(xié)議族; socket.remoteAddress:進程IP地址。
Node.js在創(chuàng)建一個TCP客戶端的時候同樣使用的是net(網絡)模塊。
2.1、使用Node.js創(chuàng)建TCP客戶端
為了使用Node.js創(chuàng)建TCP客戶端,首先要調用require(‘net’)來加載net模塊。創(chuàng)建一個TCP客戶端只需要創(chuàng)建一個連接TCP客戶端的socket對象即可:
//引入net模塊 const net = require('net'); //創(chuàng)建TCP客戶端 const client = new net.Socket();
創(chuàng)建一個socket對象的時候可以傳入一個json對象。這個對象有以下屬性:
fd:指定一個存在的文件描述符,默認值為null; readable:是否允許在這個socket上讀,默認值為false; writeable:是否允許在這個socket上寫,默認值為false; allowHalfOpen:該屬性為false時,TCP服務器接收到客戶端發(fā)送的一個FIN包后,將會回發(fā)一個FIN包;該屬性為true時,TCP服務器接收到客戶端發(fā)送的一個FIN包后不會回發(fā)FIN包。
2.2、連接TCP服務器
創(chuàng)建了一個socket對象后,調用socket對象的connect()方法就可以連接一個TCP服務器,代碼如下:
//引入net模塊 const net = require('net'); //創(chuàng)建TCP客戶端 const client = new net.Socket(); //設置連接的服務器 client.connect(8001, '127.0.0.1', function () { console.log("連接服務器成功"); });
連接成功如下圖所示:
2.3、獲取從TCP服務器發(fā)送的數(shù)據(jù)
socket對象有data、error、close、end等事件,因可以通過監(jiān)聽data事件來獲取從TCP服務器發(fā)送的數(shù)據(jù),代碼如下:
//引入net模塊 const net = require('net'); //創(chuàng)建TCP客戶端 const client = new net.Socket(); //設置連接的服務器 client.connect(8001, '127.0.0.1', function () { console.log("連接服務器成功"); }); //監(jiān)聽data事件 client.on("data", function (data) { //打印數(shù)據(jù) console.log("接收到數(shù)據(jù)為:" + data.toString()); });
先啟動TCP服務端,再運行上面客戶端,可以發(fā)現(xiàn)命令行中已經輸出了來自服務端的數(shù)據(jù),說明此時已經實現(xiàn)了服務端和客戶端之間的通信:
2.4、向TCP服務器發(fā)送數(shù)據(jù)
因為TCP客戶端是一個socket對象,所以可以使用以下代碼來向TCP服務器發(fā)送數(shù)據(jù):
//引入net模塊 const net = require('net'); //創(chuàng)建TCP客戶端 const client = new net.Socket(); //設置連接的服務器 client.connect(8001, '127.0.0.1', function () { console.log("連接服務器成功"); //給服務端發(fā)送數(shù)據(jù) client.write("Hello Server......"); }); //監(jiān)聽data事件 client.on("data", function (data) { //打印數(shù)據(jù) console.log("接收到數(shù)據(jù)為:" + data.toString()); }); //監(jiān)聽end事件 client.on("end", function () { console.log("客戶端發(fā)送數(shù)據(jù)結束") });
客戶端控制臺輸出:
服務端控制臺輸出:
關于如何使用Node.js進行TCP網絡通信就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。