我正在研究一个node.js对等发现/管理库。我在使用TCP服务器/客户端时遇到了一个奇怪的问题,其中一些数据显示为已写入流中,但从未收到(通过以太网和wifi在多个设备上进行了测试)。
两个设备都有一个使用net.createServer()的TCP服务器,并通过net.createConnection()将连接发送到另一台设备的服务器。已经考虑了分块,并且在发送数据之前,发送了主体大小的32位整数。请注意,所有内容均以打字稿编写,但我在香草node.js中附加了最小的可复制性。 DataBuffer类处理分块。
最小可重复性:
const net = require('net');
const events = require("events")
class DataBuffer extends events.EventEmitter {
constructor() {
super();
this.state = 0;
this.payload = null;
this.payloadSize = -1;
this.index = 0;
}
static createHeader(size) {
const header = Buffer.allocUnsafe(4);
header.writeUInt32BE(size, 0);
return header;
}
static writeClient(client, data, callback, autoClose = false) {
if (client.writable) {
client.write(DataBuffer.createHeader(data.length), (err) => {
if (err) {
console.log(err);
}
else {
client.write(data, err1 => {
if (err1) {
console.log(err1);
}
else {
console.log('data written!');
if (autoClose) {
client.end();
}
if (callback) {
callback();
}
}
});
}
});
}
}
readBytes(data) {
switch (this.state) {
case 0: {
this.payloadSize = data.readUInt32BE(0);
this.payload = Buffer.allocUnsafe(this.payloadSize);
data.copy(this.payload, 0, 4);
this.index = data.length - 4;
this.state = 1;
console.log('header size:', this.payloadSize);
break;
}
case 1: {
data.copy(this.payload, this.index);
this.index += data.length;
console.log('bytes read:', this.index);
if (this.index === this.payloadSize) {
this.state = 0;
this.emit('done', this.payload);
this.payload = null;
this.payloadSize = -1;
this.index = 0;
}
break;
}
}
}
}
const server = net.createServer(client => {
let dataBuffer = new DataBuffer();
client.on('data', data => {
try {
dataBuffer.readBytes(data);
} catch (e) {
client.destroy();
throw e;
}
});
dataBuffer.on('done', (data) => {
console.log(data.toString());
});
client.on('end', (err) => {
if (err) {
throw err;
}
});
client.on('timeout', err => {
if (err) {
throw err;
}
});
client.on('close', (err) => {
if (err) {
throw err;
}
});
client.on('lookup', (err) => {
if (err) {
throw err;
}
});
client.on('error', err => {
throw err;
});
}).listen(18235);
setTimeout(() => {
const ip = process.env.NODE_IP === '192.168.0.5' ? '192.168.0.6' : '192.168.0.5';
const message = 'some random data from: ' + ip;
const conn = net.createConnection({ host: ip, port: 18235 }, () => {
DataBuffer.writeClient(conn, message, undefined, true);
});
}, 5000);
假定设备A在192.168.0.5上,设备B在192.168.0.6上。 NODE_IP是相应设备上的环境变量。我已经仔细检查了所有IP等。
设备A的输出:
data written!
header size: 34
设备B的输出:
header size: 34
bytes read: 34
some random data from: 192.168.0.5
data written!