【nodeJS基础】buffer、fs(文件系统)、dgram(udp数据报)和net(TCP网络模块)

1、buffer

buffer这个模块前端估计会很少涉及到,主要是因为前端所用的协议基本都是以json数据格式的http协议和websocket协议,都是应用层协议。buffer主要是二进制缓冲数据,这种数据格式是在网络缓冲中存在的数据,buffer也是一个类似数组。本文主要介绍buffer的写和读:

基于node内置模块buffer的基础api方法组合构造的面向对象:

  1. buffer的写对象类:
export class BufWrite {
  buf: Buffer; //要写数据的buffer
  byteOffset: number; //指针的位置(变量),用来表示从那个位置开始往后写数据
  endIndex: number = 0; //写有数据的最后位置
  startIndex: number = 0; //buffer第一个数据的位置
  constructor(byteOffset: number = 0, byteLength: number = 200 ) {
    this.buf = Buffer.alloc(byteLength); 
    this.byteOffset = byteOffset;
    this.startIndex = byteOffset;
  }

  writeDoubleLE(value: number): void {
   this.byteOffset = this.buf.writeDoubleLE(value, this.byteOffset);
  }

  writeUIntLE(value: number, byteLength: number): void {
    this.byteOffset = this.buf.writeUIntLE(value, this.byteOffset, byteLength);
  }

  getEndIndex(): number {
    return this.endIndex = this.byteOffset;
  }

  getStartIndex(): number {
    return this.startIndex;
  }

  getBuf(): Buffer {
    return this.buf.slice(this.getStartIndex(), this.getEndIndex());
  }
}
  1. buffer的读对象类:
export class ReadBuffers {
  i: number;
  udpBuf: Buffer;
  constructor(udpBuf: Buffer, i: number = 6) {
  //i=6 跳过头部非data数据
    this.i = i;
    this.udpBuf = udpBuf;
  }
  readDoubleLE() {
    const data = this.udpBuf.readDoubleLE(this.i);
    this.i += 8;
    return data;
  }

  toString(bytes: number): string {
    const data: string = this.udpBuf.toString("utf8", this.i, this.i + bytes);
     this.i += bytes; 
    return data;
  }

  readUIntLE(bytes: number): number {
    const data: number = this.udpBuf.readUIntLE(this.i, bytes);
    this.i += bytes;
    return data;
  }
}

这样做主要是把基础的api组合成类,这样读的时候从哪个位置开始内部指针直接自己算好了,写的时候从哪个位置开始写也自动写好了。优化不需要调研基础api给buffer的位置和计算位置了。

2、fs文件系统

/**
 * node.js读取文件基础模块
 */
const fs = require("fs-extra");
const neatCsv = require("neat-csv");
//out

/**
 * read single csv file--target point
 * @param {*} csvPath
 * @returns
 */
const readCsv = async (csvPath) => {
  return new Promise((resolve, reject) => {
    fs.readFile(csvPath, "utf-8", async (err, res) => {
      resolve(await neatCsv(res));
    });
  });
};

/**
 * readFile适用有type属性的文件单个异步读取
 * @param {*} file
 * @returns
 */
const readFile = (file) => {
  if (file.type !== "application/json") {
    const error = "请导入json场景文件";
    return Promise.reject(error);
  }
  return new Promise((resolve, reject) => {
    fs.readJson(file.path, (err, data) => {
      if (err) {
        const error = "该json文件格式错误";
        reject(error);
      } else {
        resolve(data);
      }
    });
  });
};

/**
 * 适用electron读取单个文件方法
 * @param {*} filePath
 * @returns
 */
const electronReadFile = (filePath) => {
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, (err, data) => {
      if (err) {
        const error = "该文件格式错误";
        reject(error);
      } else {
        resolve(JSON.parse(data));
      }
    });
  });
};

/**
 * inputReadFiles一个或多个readFile异步读取,使用于HTML的input文件事件
 * @param {*} files
 * @returns
 */
const inputReadFiles = async (e) => {
  const files = e.target.files;
  const promisesOut = [];
  files.forEach((file) => {
    promisesOut[promisesOut.length] = readFile(file);
  });

  return Promise.all(promisesOut).then((res) => {
    return Promise.resolve(res[0]);
  });
};

//保存文件基础函数
const saveFile = (filePath, data) => {
  return fs.outputFile(filePath, data, (err) => {
    if (err) {
      console.log(
        "🚀 ~ file: dfhFileIO.ts ~ line 49 ~ fs.outputJson ~ err",
        err
      );
    }
    const msg = `文件已保存至${filePath}`;
    return Promise.resolve(msg);
  });
};

export { saveFile, electronReadFile, readCsv };

3、dgram(udp套接字)

  1. 监听端:
const address ={
port:5000,
address:,
}
const MULTICASTADDR = "224.0.1.123"; //主播ip
const dgram = require("dgram");
const client = dgram.createSocket("udp4");
client.bind(port, () => {
  client.setRecvBufferSize(recvBufferSize * 1024 * 1024); //100*1000*1000字节 100M
  client.addMembership(MULTICASTADDR);
  console.log("该服务实际能接收的缓存大小", client.getRecvBufferSize(), "bit");
});

client.on("listening", function () {
  const address = client.address();
  console.log("listening on:" + MULTICASTADDR + ":" + address.port);
  console.log("address on:" + address.address);
});

client.on("error", function (err) {
  console.log("server error:\n" + err.stack);
});

process.on("uncaughtException", (err) => {
  console.error(err && err.stack);
});

client.on("close", function (err) {
  console.log("server error:\n" + err.stack);
});
client.on("message", function (msg: Buffer, rinfo) {
  console.log("🚀 ~ file: main.ts ~ line 18 ~ msg", msg);
});
  1. 发送端:
const client = require("dgram").createSocket("udp4");

client.on("error", (err) => {
  console.log("socket已关闭");
});

client.on("error", (err) => {
  console.log(err);
});

client.on("listening", () => {
  let a = Buffer.alloc(10);
  client.setSendBufferSize(100 * 1024 * 1024);
  client.send(a, 5000, "224.0.1.123");
});

client.on("message", (msg, rinfo) => {
  console.log(`msg from client ${rinfo.address}:${rinfo.port}`);
});

client.bind(6000, () => {
  client.setMulticastTTL(128);
  client.addMembership("224.0.1.123");
});

  1. websocket模块
const WebSocketServer = require("ws").Server;
let wss = new WebSocketServer({ 8088 });
let wsArr = [];
wss.on("connection", function (ws) {
  console.log("websocket连接成功");
  wsArr.push(ws);
  ws.on("close", (e) => {
    wsArr = wsArr.filter((item) => item !== ws);
    console.log("连接断开", e);
  });
});

4、net网络模块(tcp服务端和客户端)

  1. tcp服务端
const net = require("net");

const server = net.createServer();
server.listen(60000, () => {
  console.log(server.address());
});

server.on("connection", (c) => {
  c.on("data", (data) => {
   	console.log(data)
  });
  c.on("error", (err) => {
    c.destroy();
  });
});

  1. 客户端
const net = require("net");
const client = net.createConnection(60000, "localhost",()=>{
  console.log('connected to server!');
  client.write('world!\r\n');
});
client.on('data', (data) => {
  console.log(data.toString());
  client.end();
});
client.on('end', () => {
  console.log('disconnected from server');
});
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

h沐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值