實(shí)驗(yàn)簡(jiǎn)介
此實(shí)驗(yàn)主要講解TCP和UDP的網(wǎng)絡(luò)編程,net模塊提供了一個(gè)異步網(wǎng)絡(luò)包裝器,用于TCP網(wǎng)絡(luò)編程,它包含了創(chuàng)建服務(wù)器和客戶端的方法。dgram模塊用于UDP網(wǎng)絡(luò)編程。
參考鏈接:https://nodejs.org/api/net.html, https://nodejs.org/api/dgram.html
TCP Server
net模塊通過(guò)net.createServer方法創(chuàng)建TCP服務(wù)器,通過(guò)net.connect方法創(chuàng)建客戶端去連接服務(wù)器。
通過(guò)net模塊創(chuàng)建一個(gè)TCP Server:
<pre>
// server.js
var net = require('net');
// 創(chuàng)建TCP服務(wù)器
var server = net.createServer(function(socket) {
console.log('client connected');
// 監(jiān)聽客戶端的數(shù)據(jù)
socket.on('data', function(data) {
console.log('server got data from client: ', data.toString());
});
// 監(jiān)聽客戶端斷開連接事件
socket.on('end', function(data) {
console.log('connection closed');
});
// 發(fā)送數(shù)據(jù)給客戶端
socket.write('Hello\r\n');
});
// 啟動(dòng)服務(wù)
server.listen(8080, function() {
console.log('server bound');
});
</pre>
然后再創(chuàng)建一個(gè)客戶端:
<pre>
// client.js
var net = require('net');
// 連接服務(wù)器
var client = net.connect({port: 8080}, function() {
console.log('connected to server');
client.write('World!\r\n');
});
// 接收服務(wù)端的數(shù)據(jù)
client.on('data', function(data) {
console.log('client got data from server: ', data.toString());
// 斷開連接
client.end();
});
// 斷開連接
client.on('end', function() {
console.log('disconnected from server');
});
</pre>
運(yùn)行測(cè)試:
在虛擬機(jī)中打開兩個(gè)終端,先運(yùn)行TCP服務(wù)器代碼:
<pre>$ node server.js</pre>
然后在另一個(gè)終端運(yùn)行TCP客戶端代碼:
<pre>$ node client.js</pre>
即可看到兩個(gè)終端運(yùn)行結(jié)果。
簡(jiǎn)易聊天室服務(wù)端
了解了基礎(chǔ)的東西,下面我們來(lái)做一個(gè)簡(jiǎn)單的聊天室吧。
首先創(chuàng)建TCP服務(wù)器,和前面一樣:
<pre>
// chatServer.js
var net = require('net');
// 創(chuàng)建TCP服務(wù)器
var server = net.createServer();
// 存儲(chǔ)所有客戶端socket
var sockets = [];
server.on('connection', function(socket) {
console.log('Got a new connection');
sockets.push(socket);
socket.on('data', function(data) {
console.log('Got data: ', data);
sockets.forEach(function(otherSocket) {
if (otherSoecket !== socket) {
otherSocket.write(data);
}
});
]);
// 新增代碼
socket.on('close', function() {
console.log('A client connection closed');
var index = sockets.indexOf(socket);
sockets.splice(index, 1);
});
});
server.on('error', function(err) {
console.log('Server error: ', err.message);
});
server.on('close', function() {
console.log('Server closed');
});
server.listen(8080);
</pre>
簡(jiǎn)易聊天室客戶端
聊天室的服務(wù)端功能基本就實(shí)現(xiàn)了,下面我們來(lái)寫一個(gè)簡(jiǎn)單的客戶端吧:
<pre>
// chatClient.js
var net = require('net');
process.stdin.resume();
process.stdin.setEncoding('utf8');
var client = net.connect({ port: 8080 }, function() {
console.log('Connected to server');
// 獲取輸入的字符串
console.log('input: ');
process.stdin.on('data', function(data) {
// 發(fā)送輸入的字符串到服務(wù)器
console.log('input: ');
client.write(data);
// 輸入 'close' 字符串時(shí)關(guān)閉連接
if (data === 'close\n') {
client.end();
}
});
});
// 獲取服務(wù)端發(fā)送過(guò)來(lái)的數(shù)據(jù)
client.on('data', function(data) {
console.log('Other user's input', data.toString());
});
client.on('end', function() {
console.log('Disconnected from server');
// 退出客戶端程序
process.exit();
});
</pre>
客戶端中用到了process這個(gè)模塊,process是一個(gè)Node.js的全局模塊,可以在任何地方
直接使用而無(wú)需通過(guò)require方法引入。process模塊允許你獲得或者修改當(dāng)前Node.js
進(jìn)程的設(shè)置。process.stdin用于獲取來(lái)自標(biāo)準(zhǔn)輸入的可讀流(Readable Stream)。
現(xiàn)在來(lái)運(yùn)行這個(gè)聊天室吧:
<pre>$ node chatServer.js</pre>
在打開多個(gè)終端窗口,運(yùn)行:
<pre>$ node chatClient.js</pre>
然后在任意運(yùn)行的客戶端輸入字符串并按回車鍵,會(huì)在服務(wù)端和其他客戶端開到這個(gè)客戶端的輸入內(nèi)容。這樣就實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的聊天室了_。
UDP Server
UDP和TCP類似,通過(guò)dgram.createSocket創(chuàng)建服務(wù)。
UDP服務(wù)器:
<pre>
// udpServer.js
var dgram = require("dgram");
var server = dgram.createSocket("udp4");
server.on("error", function(err) {
console.log("server error:\n" + err.stack);
server.close();
});
// 接收來(lái)自客戶端的消息
server.on("message", function(msg, rinfo) {
console.log("server got: " + msg.toString() + " from " + rinfo.address + ":" + rinfo.port);
});
// 監(jiān)聽服務(wù)
server.on("listening", function() {
var address = server.address();
console.log("server listening on " + address.address + ":" + address.port);
});
server.bind(41234);
// server listening 0.0.0.0:41234
</pre>
UDP客戶端:
<pre>
// udpClient.js
var dgram = require('dgram');
var client = dgram.createSocket('udp4');
var message = new Buffer('hello shiyanlou');
client.send(message, 0, message.length, 41234, 'localhost', function(err, bytes) {
client.close();
});
</pre>
發(fā)送的消息必須通過(guò)Buffer創(chuàng)建。
然后運(yùn)行服務(wù)端:
<pre>$ node server.js</pre>
再運(yùn)行客戶端:
<pre>$ node client.js</pre>
此時(shí),服務(wù)端就會(huì)收到來(lái)自客戶端的消息。
Node.js基礎(chǔ)的網(wǎng)絡(luò)編程就講到這里了。