dgram
dgram模块提供UDP数据报套接字的实现。
dgram-server.js
let dgram = require('dgram')
const server = dgram.createSocket('udp4');
server.on('error', (err) => {
console.log(`server errorf服务端异常:\n${err.stack}`);
server.close();
});
server.on('message', (msg, rinfo) => {
console.log(`server got服务器接收消息来自: ${msg} from ${rinfo.address}:${rinfo.port}`);
});
server.on('listening', () => {
const address = server.address();
console.log(`server listening服务器监听 ${address.address}:${address.port}`);
});
server.bind(41234);
// Prints: server listening 0.0.0.0:41234
dgram-client.js
let dgram = require('dgram')
let { Buffer } = require('buffer')
const message = Buffer.from('Some bytes一些字节');
const client = dgram.createSocket('udp4');
client.send(message, 41234, 'localhost', (err) => {
// 记得关闭
client.close();
});
// client.send('一些字节', 41234, 'localhost', (err) => {
// client.close();
// });
Stream (流)
流操作的好处
1)流是边读边写的,读取一段文件,就将它写入,而不必将所有的数据直接读入到内存中,提高内存使用效率
2) 当获得数据之后即可立即开始处理数据,这样所需的时间更少,而必须等到所有数据之后才开始处理
Node.js 中有四种基本的流类型
const { Readable, Writable, Duplex, Transform } = require('stream')
Readable - 可读的流 (例如 fs.createReadStream())。
Writable - 可写的流 (例如 fs.createWriteStream()).
Duplex - 可读写的流(双工流) (例如 net.Socket).
Transform - 转换流 在读写过程中可以修改和变换数据的 Duplex 流 (例如 zlib.createDeflate())
所有的流都继承自EventEmitter,所有可以使用on emit off once等事件
可写流和可读可写流参考这个: 链接
可读流如下
可读流(供程序消费的流)的常见形式: 读取磁盘文件和读取网络请求的内容
可读流流程(默认是暂停模式,实例.read()从缓存区拿数据,读到null代表数据读取完成了),事件,自定义可读流
// 可读流
const fs = require("fs");
let rs = fs.createReadStream("1.txt", { // 创建可读流,读取 1.txt 文件
start: 0,
end: 20,
highWaterMark: 2
});
// 存储每次读取回来的 Buffer
let bufArr = [];
// 读取文件
rs.on("data", data => {
console.log('data...', data);
// rs.pause(); // 暂停读取
// str += data; // 如果读取的文件内容是中文,每次读取的 highWaterMark 为两个字节,不能组成一个完整的汉字,在每次读取时进行 += 操作会默认调用 toString 方法,这样会导致最后读取的结果是乱码。
bufArr.push(data)
// setTimeout(() => {
// rs.resume(); // 恢复读取
// }, 1000)
});
// 监听读取结束
rs.on("end", () => { // 我们希望最后读到的结果是完整的,所以我们需要把每一次读到的结果在 data 事件触发时进行拼接
console.log("读完了",Buffer.concat(bufArr).toString());
// console.log(str)
});
rs.on("err", err => {
console.log(err);
});
// 打开和关闭文件的监听
rs.on("open", () => { // 只要创建了可读流就会打开文件触发 open 事件
console.log("open");
});
rs.on("close", () => { // 只有开始读取文件并读完后,才会关闭文件并触发 close 事件
console.log("close");
});
自定义流
-可读流
-可写流
请求是可读流,响应是可写流(用于将数据写入指定位置)
使用流操作数据的好处是不会撑爆内存的原理是read方法执行的时候会判读想要写入的数据量是否是流中设置的缓存大小上限,如果是小于的正常写入read方法返回true, 反之大于的话返回false这时就不能一次性写入
事件
pipe事件: 可读流调用pipe()方法时触发
unpipe事件: 可读流调用 unpipe() 方法时触发
(end finish等必备事件)
-双工流和转换流
可读流和可写流: 连接