【问题标题】:NodeJS TCP Server, onData small chunksNodeJS TCP 服务器,onData 小块
【发布时间】:2012-10-28 02:25:53
【问题描述】:

我做了一个简单的 NodeJS TCP 服务器,一个 Java 客户端发送一个图像:

encodedImage = <a base64 encoded image>
out.write("IMG;" + encodedImage);
out.flush();

我的NodeJS服务器如下:

net.createServer(function(TCPSocket){
        TCPSocket.on("data", function(data){
            console.log("TCP Recieved: " + data.length);    
        });
}).listen(5000);

但是,即使我发送所有数据并立即刷新,输出如下:

TCP Recieved: 13
TCP Recieved: 1344
TCP Recieved: 1344
TCP Recieved: 1344
TCP Recieved: 1344
TCP Recieved: 1344
TCP Recieved: 1472
TCP Recieved: 1344
TCP Recieved: 1344
TCP Recieved: 1344
TCP Recieved: 1344

我希望它以一个简单的块接收它,但我认为它是由于 NodeJS 的事件处理机制而发生的,对于作为单个块发送的数据实现单个块数据的最佳方法是什么?据我所知,一个 TCP 窗口可以比 1344 字节的数据大得多。我想过将标头值用作 HTTP,所以我知道长度广告构造了我想要的对象。

【问题讨论】:

  • 这就是 tcp 的工作方式。不仅在节点中,而且在任何地方。你无法控制这一点。你不应该尝试。在编写 tcp 服务器时,始终假设数据以随机大小的块进入。
  • 是的,我知道 TCP 是一个流协议,但我想知道是否有办法在收到特定数量的数据时触发事件,比如 java 的套接字读取,但我需要做一个缓冲机制

标签: java node.js networking tcp


【解决方案1】:

你是对的,在 Node 中数据会分块。您需要保留一个缓冲区,连接所有进入的块,然后当套接字关闭时,将数据写入文件系统。这是一个能够接收图像的示例:

net = require('net');
fs = require('fs');

net.createServer(function(socket){
  var buffer = new Buffer(0, 'binary');

  socket.on("data", function(data){
    buffer = Buffer.concat([buffer, new Buffer(data,'binary')]);
  });

  socket.on("end", function(data) {
    fs.writeFile("image.jpg", buffer, function(err) {
      if(err) {
        console.log(err);
      } else {
        console.log("Socket[" + socket.name + "] closed, wrote data out to sinfo.data");
      }
    }); 

  });

}).listen(5000);

console.log('ready');

我使用netcat向它发送了一张图片:

$ netcat localhost 5000 < input.jpg

【讨论】:

  • 为什么不直接将收到的数据块写入磁盘?将整个图像缓存在内存中然后写入磁盘是很浪费的。
  • @josh3736:您的评论正是我正在尝试的。我将一个 base64 编码的套接字流从客户端发送到服务器。服务器应该从传入的块中写入一个图像文件。你知道如何正确地将这些块写入写入流以节省内存吗?这是我的问题:stackoverflow.com/questions/22214267/write-base64-chunks-into-writestream
  • 我错过了什么吗?你不能只使用管道吗? socket.pipe(fs.createWriteStream(filePath));
  • 而不是连接缓冲区做var list = []; list.push(buffer); .... var final_buffer = Buffer.concat(list);
  • 如果我不断收到来自 tcp 的缓冲区(带有一些图像),我怎么知道它会完成?有没有办法在没有结束事件的情况下做到这一点?
猜你喜欢
  • 2015-10-14
  • 2018-11-24
  • 2014-03-21
  • 2017-06-26
  • 2021-11-29
  • 1970-01-01
  • 2021-09-18
  • 2013-07-01
  • 2017-12-23
相关资源
最近更新 更多