通过TCP向Node.js发送文件

3
我将翻译如下:

我正在努力学习Node.js,其中一个我一直想要实现的是让Node作为监听服务器模拟一个简单的文件传输代理。这需要Node监听TCP socket请求,然后接受二进制数据流并将其存储在系统中。

目前为止,我已经有了以下代码,其中服务器仍然不存储任何内容,只输出它收到的数据,或者应该输出:

服务器端:

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

var server = net.createServer(function() {
    console.log('server connected');
});

var HOST = '127.0.0.1';
var PORT = '9001'
var FILEPATH = '/home/steve/Downloads/';


server.listen(PORT, HOST, function() {
    //listening
    console.log('server bound to ' + PORT + '\n');

    server.on('connection', function(){
        console.log('connection made...\n')
    })

    server.on('data', function(data) {
        console.log('data received');
        console.log('data is: \n' + data);
    });


});

为了保持简单,我也写了一个Node的客户端。

客户端:

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


var PORT = 9001;
var HOST = '127.0.0.1';
var FILEPATH = '/home/steve/Work/Node.js/FileTransfer/random.fil';

var client = new net.Socket()

//connect to the server
client.connect(PORT,HOST,function() {
    'Client Connected to server'

    //send a file to the server
    var fileStream = fs.createReadStream(FILEPATH);
    fileStream.on('error', function(err){
        console.log(err);
    })

    fileStream.on('open',function() {
        fileStream.pipe(client);
    });

});

//handle closed
client.on('close', function() {
    console.log('server closed connection')
});

client.on('error', function(err) {
    console.log(err);
});

当我运行它们时,没有出现任何错误,但服务器仅创建服务器,接受连接然后关闭连接。除此之外,我似乎无法解决问题。此外,是否将其用于传输大文件(约1GB)是一个不错的选择,还是Node不适合这样的操作?
谢谢!
2个回答

6

我认为你在误用服务器。当你调用net.createServer时,传递给其回调函数会在每次新连接建立时被调用。传递给回调函数的参数是连接本身,你需要监听该连接的数据事件。我认为以下是更符合你需求的方式:

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

var server = net.createServer(function(conn) {
    console.log('server connected');

    conn.on('data', function(data) {
        console.log('data received');
        console.log('data is: \n' + data);
    });
});

var HOST = '127.0.0.1';
var PORT = '9001'
var FILEPATH = '/home/steve/Downloads/';


server.listen(PORT, HOST, function() {
    //listening
    console.log('server bound to ' + PORT + '\n');

    server.on('connection', function(){
        console.log('connection made...\n')
    })
});

或者,您可以在服务器连接事件中完成此操作。这也会传递一个连接对象:

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

var server = net.createServer(function(conn) {
    console.log('server connected');

});

var HOST = '127.0.0.1';
var PORT = '9001'
var FILEPATH = '/home/steve/Downloads/';

server.listen(PORT, HOST, function() {
    //listening
    console.log('server bound to ' + PORT + '\n');

    server.on('connection', function(conn) {
        console.log('connection made...\n')
        conn.on('data', function(data) {
            console.log('data received');
            console.log('data is: \n' + data);
        });
    })
});

重点是,在连接上监听数据,而不是在服务器本身上进行监听。

非常感谢,第一次就解决了问题。那么,如果我想继续这个例子,如何将二进制数据管道传输到特定的文件路径?此外,在您的经验中,Node.js是否适合这样的服务器,还是应该坚持使用Python在Twisted上面进行开发? - SteveMustafa
好的,所以我已经从fs创建了一个可写文件流,并将连接与fs连接起来,代码如下: var fileStream = fs.createWriteStream(FILEPATH + 'output.bin'); conn.pipe(fileStream); 现在,我注意到了两件事情。1)两个文件的 MD5 校验和不同,这让我感到很有趣。2. 我收到了一个关于附加了11个发射器的内存泄漏警告。3. 我需要学习如何做出响应而不是评论:s - SteveMustafa

0

我不知道为什么校验和不同,我尝试了但对我来说似乎是相等的。关于第二个问题,请查看此链接http://nodejs.org/api/events.html#events_emitter_setmaxlisteners_n。 API表示:“如果为特定事件添加了超过10个侦听器,则EventEmitters将打印警告”,并且“设置为零表示无限制”。


谢谢你,Matteo。我需要重新检查一下自己的东西。感谢你的第二个回答,但是这就引出了一个问题,我在上面的代码中设置或使用了超过10个事件监听器吗? - SteveMustafa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接