Javascript node.js在p2p文件下载中写入文件流混乱
伙计们。我尝试使用node.js创建一个p2p文件共享应用程序。下载文件时,它将逐块下载文件 以下代码中使用的块大小为1KB。但它有一个问题,当可用套接字数MAX_SOCKET_CNT设置为30时,它将无法工作 如何运行代码: 首先,运行Javascript node.js在p2p文件下载中写入文件流混乱,javascript,node.js,download,filestream,p2p,Javascript,Node.js,Download,Filestream,P2p,伙计们。我尝试使用node.js创建一个p2p文件共享应用程序。下载文件时,它将逐块下载文件 以下代码中使用的块大小为1KB。但它有一个问题,当可用套接字数MAX_SOCKET_CNT设置为30时,它将无法工作 如何运行代码: 首先,运行node server.js,然后运行node client.js,这将把名为fav.mp3的文件下载到fav local.mp3 下载后,尝试运行diff fav.mp3 fav local.mp3检查文件是否已完全下载 你能帮我找出问题出在哪里吗 欢迎任何回
node server.js
,然后运行node client.js
,这将把名为fav.mp3
的文件下载到fav local.mp3
下载后,尝试运行diff fav.mp3 fav local.mp3
检查文件是否已完全下载
你能帮我找出问题出在哪里吗
欢迎任何回答或建议。提前谢谢
以下是源代码:
server.js
client.js
var http=require('http');
var fs=需要('fs');
var remoteFile='fav.mp3';
var fileSize=439355;
var localFile='fav-local.mp3';
var totalBlocks=Math.floor((文件大小+1023)/1024);
/**************************************************/
//重点
var MAX_SOCKET_CNT=总块数//工作
//var MAX_SOCKET_CNT=30//由于递归下载块函数,无法工作//????
/*************************************************/
对于(var i=0;i=TotalBlocksUM)回报;
变量块大小=1024;
var file=fs.createWriteStream(localFile,{start:blockID*BLOCK_SIZE});
var request=http.get(“http://localhost:“+端口+”/download_block?block_id=“+blockID,函数(响应){
管道(文件);
on('finish',function(){
var callback=函数downloadBlockOver(){
console.log(“完成下载blockID:+blockID”);
var nextBlockID=blockID+MAX\u SOCKET\u CNT;
如果(nextBlockIDAha。
最后,我找到了解决方案。您必须先创建文件,然后在下载之前将write stream的标志更改为“r+”
function touchFile(fileName,fileSize){
var BLOCK_SIZE=1024;
var totalBlocks=Math.floor((fileSize+BLOCK_SIZE-1)/BLOCK_SIZE);
var file = fs.createWriteStream(fileName);
var blockBuffer=new Buffer(BLOCK_SIZE);
for(var i=0;i<totalBlocks-1;++i){
file.write(blockBuffer,0, BLOCK_SIZE);
}
var leftToFill=new Buffer(fileSize-(totalBlocks-1)*BLOCK_SIZE);
file.write(leftToFill,0, leftToFill.Length);
file.end();
}
到
它现在可以工作了。当MAX\u SOCKET\u CNT==3时,触摸文件就可以工作了。
最终解决方案是使用节点模块随机访问文件:
client.js代码:
var http=require('http');
var fs=需要('fs');
var randomAccessFile=require('random-access-file');
var remoteFile='fav.mp3';
var fileSize=439355;
//var fileSize=6000;//363213;//439355;
var localFile='fav-local.mp3';
var totalBlocks=Math.floor((文件大小+1023)/1024);
/**************************************************/
//重点
//var MAX_SOCKET_CNT=totalBlocks;//已工作
var MAX_SOCKET_CNT=20;//已工作
/*************************************************/
var file=randomAccessFile('fav-local.mp3');
对于(var i=0;i=TotalBlocksUM)回报;
变量块大小=1024;
var chunks=[];
var request=http.get(“http://localhost:“+端口+”/download_block?block_id=“+blockID,函数(响应){
响应.on('data',函数(块){
推(chunk);
});
关于('error',函数(e){
console.log('错误……'+e);
});
on('close',函数(){
console.log('close…');
});
on('end',函数(){
var dataToProcess=Buffer.concat(块);
log('块数据大小:'+dataToProcess.length);
file.write(块ID*块大小,数据处理,
功能(err){
如果(错误){
日志(“写入错误…”);
}否则{
var nextBlockID=blockID+MAX\u SOCKET\u CNT;
if(nextBlockID
var http = require('http');
var fs = require('fs');
var remoteFile='fav.mp3';
var fileSize=439355;
var localFile='fav-local.mp3';
var totalBlocks=Math.floor((fileSize+1023)/1024);
/**************************************************/
//KEY POINT
var MAX_SOCKET_CNT=totalBlocks; //worked
//var MAX_SOCKET_CNT=30;//not work //????because of recursive downloadBlock function????
/*************************************************/
for(var i=0;i<MAX_SOCKET_CNT;++i){
downloadBlock('127.0.0.1',8801,remoteFile, localFile,i,totalBlocks);
}
function downloadBlock(IP,PORT,remoteFile,localFile,blockID,totalBlocksNum){
if(blockID >= totalBlocksNum) return;
var BLOCK_SIZE=1024;
var file = fs.createWriteStream(localFile,{start: blockID*BLOCK_SIZE});
var request = http.get("http://localhost:"+PORT+"/download_block?block_id="+blockID, function(response) {
response.pipe(file);
file.on('finish', function() {
var callback=function downloadBlockOver(){
console.log("compelete download blockID:"+blockID);
var nextBlockID=blockID+MAX_SOCKET_CNT;
if(nextBlockID<totalBlocksNum){
downloadBlock(IP,PORT,remoteFile,localFile,nextBlockID,totalBlocksNum); //why not this work if MAX_SOCKET_CNT=30???
}
}
file.close(callback);
});
});
}
function touchFile(fileName,fileSize){
var BLOCK_SIZE=1024;
var totalBlocks=Math.floor((fileSize+BLOCK_SIZE-1)/BLOCK_SIZE);
var file = fs.createWriteStream(fileName);
var blockBuffer=new Buffer(BLOCK_SIZE);
for(var i=0;i<totalBlocks-1;++i){
file.write(blockBuffer,0, BLOCK_SIZE);
}
var leftToFill=new Buffer(fileSize-(totalBlocks-1)*BLOCK_SIZE);
file.write(leftToFill,0, leftToFill.Length);
file.end();
}
var file = fs.createWriteStream(localFile,{start: blockID*BLOCK_SIZE});
var file = fs.createWriteStream(localFile,{start: blockID*BLOCK_SIZE,flags:'r+',autoClose: true});
var http = require('http');
var fs = require('fs');
var randomAccessFile = require('random-access-file');
var remoteFile='fav.mp3';
var fileSize=439355;
//var fileSize=6000;//363213; //439355;
var localFile='fav-local.mp3';
var totalBlocks=Math.floor((fileSize+1023)/1024);
/**************************************************/
//KEY POINT
//var MAX_SOCKET_CNT=totalBlocks; //worked
var MAX_SOCKET_CNT=20;//worked
/*************************************************/
var file = randomAccessFile('fav-local.mp3');
for(var i=0;i<MAX_SOCKET_CNT;++i){
downloadBlock('127.0.0.1',8801,remoteFile, localFile,i,totalBlocks);
}
file.close();
function downloadBlock(IP,PORT,remoteFile,localFile,blockID,totalBlocksNum){
if(blockID >= totalBlocksNum) return;
var BLOCK_SIZE=1024;
var chunks=[];
var request = http.get("http://localhost:"+PORT+"/download_block?block_id="+blockID, function(response) {
response.on('data', function (chunk) {
chunks.push(chunk);
});
response.on('error', function (e) {
console.log('error.......'+e);
});
response.on('close', function () {
console.log('close ....');
});
response.on('end', function () {
var dataToProcess=Buffer.concat(chunks);
console.log('block data size: ' + dataToProcess.length);
file.write(blockID*BLOCK_SIZE, dataToProcess,
function(err) {
if(err){
console.log("error in write...");
}else{
var nextBlockID=blockID+MAX_SOCKET_CNT;
if(nextBlockID<totalBlocksNum){
console.log("download next block:"+nextBlockID);
downloadBlock(IP,PORT,remoteFile,localFile,nextBlockID,totalBlocksNum);
}
}
}
);
});
});
}