如何在Nodejs中一次性通过TCP发送文件

时间:2016-04-04 08:38:12

标签: node.js tcp

我想使用Nodejs通过tcp / ip发送文件,我使用的文件大小小于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 chatmpotra中提出这个问题,这对我来说是有道理的解释。

  

这不是问题。   这就是流式传输的工作方式:将大型数据包发送到较小的数据包中。   如果您唯一的愿望是增加缓冲区大小以便将文件接收到一个单一的数据事件中,那么您就会认为它错了。如果你的文件有500MB,根据你的期望,服务器和客户端都必须分配500MB!进入内存,只是为了满足单个数据事件的需要;这显然是错误的数据传输方法。

2 个答案:

答案 0 :(得分:3)

节点发送整个缓冲区就好了,但是你的客户端将以块的形式发出数据事件。如果要接收整个文件,则需要缓冲块:

const chunks = []
client.on('data', chunk => chunks.push(chunk))
client.on('end', () => {
  const file = Buffer.concat(chunks)
  // do what you want with it
})

我不知道控制Node中何时发出数据事件的方法。

答案 1 :(得分:1)

我认为你需要调整你的内核缓冲区:

# 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

对于Windows,请查看here