在Node.js中,net模块实现了基于TCP的数据通信
let net = require('net');
function connectionListener(socket){
console.log('客户端已经链接')
}
net.createServer(options,connectionListener);
--------------或者---------------
server.on('connection',connectionListener);
server.listen(8080,'hostname',function(){
console.log('服务器开始监听')
});
server.address();
设置最大链接数以及监听客户端的链接数量
server.getConnections((err,count)=>{
console.log('已经链接'+count+'个用户')
});
server.maxConnections = 2;
使用close方法可以显式拒绝所有的客户端的连接请求,当所有已连接的客户端关闭后服务器会自动关闭,并触发服务器的close事件,只有close方法才会触发close事件
server.close();
server.on('close',callback);
unref方法指定发客户端连接被全部关闭时退出应用程序
server.unref();
net.Socket代表一个socket端口对象,他是一个双工流
获取客户端地址
let net = require('net');
let server = net.createServer(function(socket){
console.log(socket.address())
});
server.listen(8080);
let net = require('net');
let server = net.createServer({allowHalfOpen:true},function(socket){
socket.setEncoding('utf8');
socket.on('data',function(data){
console.log(data);
})
socket.on('end',function(){
console.log('客户都按关闭')
})
});
server.listen(8080)
pipe方法可以将客户端发送的数据写到文件或其它目标中。
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);
});
});
});
像客户端写数据
socket.write(data,[encoding],[callback]);
write的返回值和bufferSize属性值
let net = require('net');
let fs = require('fs');
let path = require('path');
let server = net.createServer({ allowHalfOpen: true }, function (socket) {
console.log("客户端已经连接");
socket.setEncoding('utf8');
let rs = fs.createReadStream(path.resolve(__dirname, '1.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) {
console.log("缓存区已全部发送")
});
});
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.on('timeout', function () {
socket.end(); // 超时关闭
});
//socket.setTimeout(0);取消超时时间的设置
});
server.listen(8080);
pause可以暂停data事件触发,服务器会把客户端发送的数据暂存在缓存区里
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);
当服务器和客户端建立连接后,当一方主机突然断电、重启、系统崩溃等意外情况时,将来不及向另一方发送FIN包,这样另一方将永远处于连接状态。 可以使用setKeepAlive方法来解决这一个问题
socket.setKeepAlive([enaable],[initialDelay]);
let socket = new net.Socket(options);
socket.connect(port, host, callback);
----------或者-----------
socket.on('connect', callback);
let net = require('net');
let clients = {}
let server = net.createServer(function (socket) {
server.getConnections((err, count) => {
socket.write(`欢迎你来到聊天室最多容纳${server.maxConnections}人 当前${count}人,请输入用户名\r\n`);
});
socket.setEncoding('utf8');
let nickname;
socket.on('data', function (data) {
data = data.replace(/\r\n/,'')
if(nickname){
broadcast(nickname,`${nickname}:${data}`);
}else{
nickname = data;
clients[nickname] = socket;
broadcast(nickname,`欢迎${data}参加聊天室\r\n`)
}
});
socket.on('end', function () {
console.log('离开聊天室');
socket.destroy();
delete clients[nickname]
});
});
function broadcast(username,content){
for(let key in clients){
if(key !== username){
clients[key].write(content+'\r\n');
}
}
}
server.listen(8080);
// 当输入l:时 显示在线用户列表
// n:灰灰
// s:灰灰:内容
// b:群发
// 瞎写 提时命令不存在
let net = require('net');
let clients = {}
let server = net.createServer(function (socket) {
let key = socket.remoteAddress + socket.remotePort;
clients[key] = { nickname: '匿名', socket };
server.getConnections((err, count) => {
socket.write(`欢迎你来到聊天室最多容纳${server.maxConnections}人 当前${count}人,请输入用户名\r\n`);
});
socket.setEncoding('utf8');
let nickname;
socket.on('data', function (data) {
data = data.replace(/\r\n/, '');
let type = data.split(':')[0];
console.log(type)
switch (type) {
case 'l':
list(socket);
break;
case 'n':
rename(key, data.split(':')[1])
break;
case 's':
private(data.split(':')[1], data.split(':')[2])
break;
case 'b':
broadcast(key, data.split(':')[1])
break;
default:
socket.write('输入有误\r\n')
}
});
socket.on('end', function () {
console.log('服务端关闭');
clients[key].socket.destroy();
delete clients[key];
});
});
function list(socket) {
let users = [];
Object.keys(clients).forEach(key => {
users.push(clients[key].nickname);
});
socket.write('当前用户列表\r\n:' + users.join('\r\n') + '\r\n');
}
function rename(key, name) {
clients[key].nickname = name
}
function broadcast(key, content) {
for (let k in clients) {
if (key !== k) {
clients[k].socket.write(content + '\r\n');
}
}
}
function private(nickname, content) {
let socket;
for (let key in clients) {
if (clients[key].nickname === nickname) {
socket = clients[key].socket;
}
}
if (socket) {
socket.write(content + '\r\n')
}
}
server.listen(8080);
let dgram = require('dgram');
let socket = dgram.createSocket('udp4');
socket.on('message',function(msg,rinfo){
console.log(msg.toString());
socket.send('你好',rinfo.port,rinfo.address)
});
socket.bind(41234,'localhost');
let dgram = require('dgram');
let socket = dgram.createSocket('udp4');
socket.send('珠峰',41234,'localhost',function(err,bytes){
console.log('send');
});
socket.on('message',function(data){
console.log(data.toString());
})
FF FB 1F FF FB 20 FF FB 18 FF FB 27 FF FD 01 FF FB 03 FF FD 03
FF FB 1F window size
FF FB 20 terminal speed
FF FB 18 terminal type
FF FB 27 Telnet Environment Option
FF FD 01 echo
FF FB 03 suppress go ahead
FF FD 03 suppress go ahead
如果不需要這些, 改用RAW模式就可以了