在Node.js中,提供了net模塊用來實現TCP服務器和客戶端的通訊。緩存
net.createServer([options][, connectionListener])
複製代碼
也能夠經過監聽connection事件的方式來指定監聽函數bash
server.on('connection',function(socket){});
複製代碼
能夠使用listen方法通知服務器開始監聽客戶端的鏈接服務器
server.listen(port,[host],[backlog],[callback])
複製代碼
server.on('listening',function(){});
複製代碼
let net = require('net');
let server = net.createServer(function(socket){
console.log('客戶端已鏈接');
});
server.listen(8080,'localhost',function(){
console.log('服務器開始監聽');
});
複製代碼
server.address()
複製代碼
查看當前與TCP服務器創建鏈接的客戶端的鏈接數量以及設置最大鏈接數量網絡
server.getConnections(callback);
server.maxConnections = 2;
複製代碼
使用close方法能夠顯式拒絕全部的客戶端的鏈接請求,當全部已鏈接的客戶端關閉後服務器會自動關閉,並觸發服務器的close事件。socket
server.close();
server.on('close',callback);
複製代碼
net.Socket表明一個socket端口對象,它是一個可讀可寫流。函數
let net = require('net');
let util = require('util');
let server = net.createServer(function(socket){
server.getConnections((err,count)=>{
server.maxConnections = 1;
console.log('最大鏈接數量%d,當前鏈接數量%d',server.maxConnections,count);
});
let address = socket.address();
console.log('客戶端地址 %s',util.inspect(address));
});
複製代碼
let server = net.createServer(function (socket) {
socket.setEncoding('utf8');
socket.on('data', function (data) {
console.log('本次收到的內容爲%s,累計收到的字節數是%d', data, socket.bytesRead);
});
});
複製代碼
let server = net.createServer(function (socket) {
socket.on('end', function () {
console.log('客戶端已經關閉');
});
});
複製代碼
pipe方法能夠將客戶端發送的數據寫到文件或其它目標中。oop
socket.pipe(destinatin,[options]);
複製代碼
let net = require('net');
let path = require('path');
let ws = require('fs').createWriteStream(path.resolve(__dirname, 'msg.txt'));
let server = net.createServer(function (socket) {
socket.on('data', function (data) {
console.log(data);
});
socket.pipe(ws, { end: false });
socket.on('end', function () {
ws.end('over', function () {
socket.unpipe(ws);
});
});
});
複製代碼
const net = require('net');
const path = require('path');
let file = require('fs').createWriteStream(path.join(__dirname, 'msg.txt'));
let server = net.createServer(function (socket) {
socket.pipe(file, {
end: false
});
setTimeout(function () {
file.end('bye bye');
socket.unpipe(file);
}, 5000);
// socket.on('end', function () {
// file.end('bye bye');
// });
});
server.listen(8080);
複製代碼
pause
能夠暫停data
事件觸發,服務器會把客戶端發送的數據暫存在緩存區裏ui
const net = require('net');
const net = require('net');
const path = require('path');
let file = require('fs').createWriteStream(path.join(__dirname, 'msg.txt'));
let server = net.createServer(function (socket) {
socket.pause();
setTimeout(function () {
socket.resume();
socket.pipe(file);
}, 10 * 1000);
});
server.listen(8080);
複製代碼
let net = require('net');
let path = require('path');
let ws = require('fs').createWriteStream(path.resolve(__dirname, 'msg.txt'));
let server = net.createServer(function (socket) {
socket.setTimeout(5 * 1000);
socket.pause();
socket.on('timeout', function () {
socket.pipe(ws);
});
//socket.setTimeout(0);取消超時時間的設置
});
server.listen(8080);
複製代碼
let socket = new net.Socket([options])
複製代碼
socket.connect(port, host, callback);
socket.on('connect', callback);
複製代碼
socket.write(data,[encoding],[callback]);
複製代碼
let net = require('net');
let server = net.createServer(function (socket) {
console.log("客戶端已經鏈接");
socket.setEncoding('utf8');
socket.on('data', function (data) {
console.log("已接收客戶端發送的數據:%s", data);
socket.write('服務器:' + data);
})
socket.on('error', function (err) {
console.log('與客戶端通訊過程當中發生了錯誤,錯誤編碼爲%s', err.code);
socket.destroy();
});
socket.on('end', function (err) {
console.log('客戶端已經關閉鏈接');
socket.destroy();
});
socket.on('close', function (hasError) {
console.log(hasError ? '異常關閉' : '正常關閉');
});
});
server.listen(808, function () {
let client = new net.Socket();
client.setEncoding('utf8');
client.connect(808, '127.0.0.1', function () {
console.log('客戶端已鏈接');
client.write('hello');
setTimeout(function () {
client.end('byebye');
}, 5000);
});
client.on('data', function (data) {
console.log('已經接收到客戶端發過來的數據:%s', data);
});
client.on('error', function (err) {
console.log('與服務器通訊過程當中發生了錯誤,錯誤編碼爲%s', err.code);
client.destroy();
});
});
複製代碼
中止server接受創建新的connections並保持已經存在的connections編碼
server.getConnections((err, count) => {
if (count == 2) server.close();
});
複製代碼
unref方法指定發客戶端鏈接被所有關閉時退出應用程序 若是將allowHalfOpen方法,必須使用與客戶端鏈接的socket端口對象的end 方法主動關閉服務器端鏈接spa
let net = require('net');
let server = net.createServer({ allowHalfOpen: true }, function (socket) {
console.log("客戶端已經鏈接");
socket.setEncoding('utf8');
socket.on('data', function (data) {
console.log("已接收客戶端發送的數據:%s", data);
socket.write('服務器確認數據:' + data);
})
socket.on('error', function (err) {
console.log('與客戶端通訊過程當中發生了錯誤,錯誤編碼爲%s', err.code);
socket.destroy();
});
socket.on('end', function (err) {
console.log('客戶端已經關閉鏈接');
socket.end();
server.unref();
});
socket.on('close', function (hasError) {
if (hasError) {
console.log('因爲錯誤致使socket關閉');
server.unref();
} else {
console.log('端口正常關閉');
}
});
server.getConnections((err, count) => {
if (count == 2) server.close();
});
});
server.listen(808, function () { });
server.on('close', function () {
console.log('服務器關閉');
});
複製代碼
write的返回值和bufferSize屬性值
let server = net.createServer({ allowHalfOpen: true }, function (socket) {
console.log("客戶端已經鏈接");
socket.setEncoding('utf8');
let rs = fs.createReadStream(path.resolve(__dirname, 'a.txt'), { highWaterMark: 2 });
rs.on('data', function (data) {
let flag = socket.write(data);
console.log("flag:", flag);
console.log('緩存字節:' + socket.bufferSize);
console.log('已發送字節:' + socket.bytesWritten);
})
socket.on('data', function (data) {
console.log('data', data);
});
socket.on('drain', function (err) {
"緩存區已所有發送"
});
});
複製代碼
當服務器和客戶端創建鏈接後,當一方主機忽然斷電、重啓、系統崩潰等意外狀況時,未來不及向另外一方發送FIN包,這樣另外一方將永遠處於鏈接狀態。 能夠使用setKeepAlive方法來解決這一個問題
socket.setKeepAlive([enaable],[initialDelay]);
複製代碼
/**
* 1.建立一個服務器
* 2. 客戶端能夠鏈接服務器
* 3.客戶端能夠發言,而後廣播給你們
* 4.客戶端鏈接和退出後都要通知你們。
* 5.顯示當前的在線人數
*/
let net = require('net');
let util = require('util');
let clients = {};
let server = net.createServer(function (socket) {
server.getConnections(function (err, count) {
socket.write(`weclome,there is ${count} users now,please input your username\r\n`);
});
let nickname;
socket.setEncoding('utf8');
socket.on('data', function (data) {
data = data.replace(/\r\n/, '');
if (data == 'byebye') {
socket.end();
} else {
if (nickname) {
broadcast(nickname, `${nickname}:${data}`);
} else {
nickname = data;
clients[nickname] = socket;
broadcast(nickname, `welcome ${nickname} joined us!`);
}
}
});
socket.on('close', function () {
socket.destroy();
});
}).listen(8088);
function broadcast(nickname, msg) {
for (let key in clients) {
if (key != nickname) {
clients[key].write(msg + '\r\n');
clients[nickname].destroy();
delete clients[nickname];
}
}
}
複製代碼
var key = scoket.remoteAddress+':'+socket.remotePort;
users[key] = {name:'匿名',socket};
socket.on('data',function(){
parse(data);
});
function parse(msg){
swtich(msg.type){
case 'secret':
secret(msg.user,msg.text);
break;
}
case 'boardcast':
boardcast(message.text);
break;
case 'cname':
cname(messsage.text);
break;
case 'list':
list();
break;
default:
socket.write('不能識別命令');
break;
}
function secret(user,text){
}
function boardcast(text){
}
function cname(text){
}
function list(){
}
複製代碼
b:text 廣播
c:nickname:text 私聊
n:nickname 更名
l 列出在線用戶列表
on('data',function(data){
if(data == 'quit){ }else if(data == 'help'){ }else(){ write(data); } }); function convert(){ } 複製代碼
let socket = dgram.createSocket(type,[callback]);
socket.on('messsage',function(msg,rinfo){});
複製代碼
socket.bind(port,[address],[callback]);
socket.on('listening',callabck;
複製代碼
若是發送數據前尚未綁定過地址和端口號,操做系統將爲其分配一個隨機端口並能夠接收任何地址的數據
socket.send(buf,offset,length,port,address,[callback]);
複製代碼
callback 制定當數據發送完畢時所須要的回調函數
獲取此socket相關的地址信息
let address = socket.address();
複製代碼
var dgram = require('dgram');
var socket = dgram.createSocket('udp4');
socket.on('message',function(msg,rinfo){
console.log(msg.toString());
console.log(rinfo);
socket.send(msg,0,msg.length,rinfo.port,rinfo.address);
});
socket.bind(41234,'localhost');
複製代碼
var dgram = require('dgram');
var socket = dgram.createSocket('udp4');
socket.on('message',function(msg,rinfo){
console.log(msg.toString());
console.log(rinfo);
});
socket.setTTL(128);
socket.send(new Buffer('zz'),0,6,41234,'localhost',function(err,bytes){
console.log('發送了個%d字節',bytes);
});
socket.on('error',function(err){
console.error(err);
});
複製代碼
建立一個UDP服務器並經過該服務器進行數據的廣播
let dgram = require('dgram');
let server = dgram.createSocket('udp4); server.on('message',function(msg){ let buf = new Bufffer('已經接收客戶端發送的數據'+msg); server.setBroadcast(true); server.send(buf,0,buf.length,41235,"192.168.1.255"); }); server.bind(41234,'192.168.1.100'); 複製代碼
let dgram = require('dgram');
let client = dgram.createSocket('udp4); client.bind(41235,'192.168.1.102);
let buf = new Buffer('hello');
client.send(buf,0,buf.length,41234,'192.168.1.100');
client.on('message',function(msg,rinfo){
console.log('received : ',msg);
});
複製代碼
把該socket端口對象添加到組播組中。
socket.addMembership(multicastAddress,[multicastInterface]);
複製代碼
socket.dropMembership(multicastAddress,[multicastInterface]);
socket.setMulticastTTL(ttl);
socket.setMulticastLoopback(flag);
複製代碼
let dgram = require('dgram');
let server = dgram.createSocket('udp4');
server.on('listening',function(){
server.MulticastTTL(128);
server.setMulticastLoopback(true);
server.addMembership('230.185.192.108');
});
setInterval(broadcast,1000);
function broadcast(){
let buffer = Buffer.from(new Date().toLocaleString());
server.send(buffer,0,buffer.length,8080,"230.185.192.108");
}
複製代碼
let dgram = require('dgram');
let client = dgram.createSocket('udp4');
client.on('listening',function(){
client.addMembership('230.185.192.108');
});
client.on('message',function(message,remote){
console.log(message.toString());
});
client.bind(8080,'192.168.1.103');複製代碼