NodeJS使用socket传输大文件

NodeJS的net模块为我们提供了socket相关API,介于此我们可以进行相关的网络编程。JavaScript 语言自身只有字符串数据类型,没有二进制数据类型,需要通过Buffer对象来处理。在这里我们读取文件时,将数据直接存储到Buffer对象里,在传输时为了统一收发时的格式,全部以十六进制进行(也可用其他)。在传输大文件时,由于内存等的限制,我们不能一次性发送数据,需要将数据不断地分块读取发送,在接收时也要分块接收写入,这就要求收发时分块起始位置要一致,文件的相关信息也需要提前指定。
NodeJS的socket接收接收到的消息都是以socket.on(‘data’,callback)回调的形式得到,可是由于网络状况,缓存状况等多种原因,每次收到的data大小不确定,在相关API中也没有找到设置每次触发回调时data大小的参数,所以就需要我们自己来判断,将data重新拼接指定大小。
上关键代码:
客户端:

function sendFile(path, name) {
    let fileInfo = fs.statSync(path);
    let fileSize = fileInfo.size;
    client.write(JSON.stringify({'id': "client2", 'fileInfo': {'fileSize': fileSize, fileName: name}}));
    let sendSize = 0;
    let packSize = 1024;
    let fd = fs.openSync(path, 'r');
    let buf = new Buffer.alloc(packSize);
    while (sendSize < fileSize) {
        //readSync参数:文件ID,buffer对象,写入buffer的起始位置,写入buffer的结束位置,读取文件的起始位置
        fs.readSync(fd, buf, 0, buf.length, sendSize);
        let data = buf.toString('hex');//以十六进制传输
        client.write(data);
        sendSize += packSize;
    }
}

服务端:

if (!socket.file_info) {//将文件信息绑定到当前socket,便于后续访问
    socket.file_info = JSON.parse(data).fileInfo;
    socket.hasSend = 0;//已经发送进来的大小
    socket.hasWrite = 0;//已经写入的大小
    socket.buf = '';//buffer存储对象
    socket.fd = fs.openSync(socket.file_info.fileName, 'w+');//文件标识ID
    socket.write('set file info');//反馈
} else {
    socket.buf += data;
    socket.hasSend = socket.hasSend + data.length;
    while (socket.buf.length >= 2048) {//开始重新拼接分块写入,十六进制下字符的大小为之前的二倍
        let pack = socket.buf.slice(0, 2048);
        socket.buf = socket.buf.slice(2048);
        pack = Buffer.from(pack, 'hex');
        fs.appendFileSync(socket.fd, pack);
    }
    // console.log(socket.hasSend,
    //     parseInt(socket.hasSend / 2 / socket.file_info.fileSize * 100) + '%');
    if (socket.hasSend >= socket.file_info.fileSize * 2) {//传输即将完毕,重置
        let buf = Buffer.from(socket.buf, 'hex');
        fs.appendFileSync(socket.fd, buf);
        fs.closeSync(socket.fd);
        console.log('file transfer completed');
        socket.write('file transfer completed');
        socket.file_info= null;
    }
}

你可能感兴趣的:(NodeJS)