如何在Nodejs中一次性通过TCP发送文件
我想通过tcp / ip发送文件,我使用的Nodejs的文件大小小于65536字节。
你设置buffersize? 是的,我愿意。
我尝试发送233565字节的图片,但看起来像nodejs分离我的文件发送多次。
这是我的示例代码
Server.js
const net = require('net'); net.bytesWritten = 300000; net.bufferSize = 300000; const fs = require('fs'); const server = net.createServer((c) => { // 'connection' listener console.log('client connected'); c.on('end', () => { console.log('client disconnected'); }); // c.write('hello\r\n'); fs.readFile('daemon0.png' , (err, data) =>{ if(!err){ console.log(data.length); c.write(data); } else { console.log('readfile daemon0 err'); } }); c.pipe(c); }); server.on('error', (err) => { throw err; }); server.listen(8124, 'localhost', () => { console.log('server bound'); });
Server.js输出
server bound client connected 233565 client disconnected
Client.js
const net = require('net'); net.bufferSize = 300000; net.bytesRead = 300000; const client = net.connect({port: 8124, address: 'localhost' }, () => { // 'connect' listener console.log('connected to server!'); client.write('world!\r\n'); }); client.on('data', (data) => { // console.log(data.toString()); console.log(net.bufferSize,data.length); client.end(); }); client.on('end', () => { console.log('disconnected from server'); });
Client.js输出
connected to server! 300000 5840 300000 65536 300000 65536 300000 65536 300000 31125 disconnected from server
作为客户端的输出,它看起来像客户端有一个限制,接收最大为65536字节的数据。 如何扩展TCP nodejs中的buffersize限制?
我问这个问题在nodejs gitter聊天和mpotra回答这个对我有意义的解释。
这不是问题。 这就是stream式传输的原理:把大的东西发送到更小的数据包。 如果你唯一的愿望是增加缓冲区的大小,以便你将文件接收到一个单一的数据事件,那么你就错了。 如果你的文件有500MB,根据你的期望,服务器和客户端将不得不分配500MB! 进入内存,只是为了满足单个数据事件的需要; 这显然是数据传输的错误方法。
节点正在发送整个缓冲区就好了,但是你的客户端将发送数据块。 如果你想接收整个文件,你需要缓冲区块:
const chunks = [] client.on('data', chunk => chunks.push(chunk)) client.on('end', () => { const file = Buffer.concat(chunks) // do what you want with it })
我不知道有什么方法来控制数据事件在Node中发出。
我认为你需要调整你的内核缓冲区:
# echo 'net.core.wmem_max=12582912' >> /etc/sysctl.conf # echo 'net.core.rmem_max=12582912' >> /etc/sysctl.conf # echo 'net.ipv4.tcp_rmem= 10240 87380 12582912' >> /etc/sysctl.conf # echo 'net.ipv4.tcp_wmem= 10240 87380 12582912' >> /etc/sysctl.conf # echo 'net.ipv4.tcp_window_scaling = 1' >> /etc/sysctl.conf # echo 'net.ipv4.tcp_timestamps = 1' >> /etc/sysctl.conf # echo 'net.ipv4.tcp_sack = 1' >> /etc/sysctl.conf # echo 'net.ipv4.tcp_no_metrics_save = 1' >> /etc/sysctl.conf # echo 'net.core.netdev_max_backlog = 5000' >> /etc/sysctl.conf //reload sysctl -p //view changes tcpdump -ni eth0
对于窗户看看这里