恢复文件传输时出现奇怪的现象。
看下面的图片你会看到坏的部分。
这种情况显然是随机的,可能每10次发生一次 我通过ftp将图片从我的Android手机发送到java服务器。
我忘记了什么。
我看到连接因java.net.SocketTimeoutException:
而被杀死
转移正在恢复,如此
Resume at : 287609 Sending 976 bytes more
完全接收文件后,字节始终是正确的。 即使是下面的图片。
Dunno从大多数时间开始调试它的位置。
任何建议或想法都会让我觉得我完全错过了一些东西。
设备发件人代码(仅发送循环):
int count = 1;
//Sending N files, looping N times
while(count <= max) {
String sPath = batchFiles.get(count-1);
fis = new FileInputStream(new File(sPath));
int fileSize = bis.available();
out.writeInt(fileSize); // size
String nextReply = in.readUTF();
// if the file exist,
if(nextReply.equals(Consts.SERVER_give_me_next)){
count++;
continue;
}
long resumeLong = 0; // skip this many bytes
int val = 0;
buffer = new byte[1024];
if(nextReply.equals(Consts.SERVER_file_exist)){
resumeLong = in.readLong();
}
//UPDATE FOR @Justin Breitfeller, Thanks
long skiip = bis.skip(resumeLong);
if(resumeLong != -1){
if(!(resumeLong == skiip)){
Log.d(TAG, "ERROR skip is not the same as resumeLong ");
skiip = bis.skip(resumeLong);
if(!(resumeLong == skiip)){
Log.d(TAG, "ERROR ABORTING skip is not the same as resumeLong);
return;
}
}
}
while ((val = bis.read(buffer, 0, 1024)) > 0) {
out.write(buffer, 0, val);
fileSize -= val;
if (fileSize < 1024) {
val = (int) fileSize;
}
}
reply = in.readUTF();
if (reply.equals(Consts.SERVER_file_receieved_ok)) {
// check if all files are sent
if(count == max){
break;
}
}
count++;
}
接收者代码(非常截断):
//receiving N files, looping N times
while(count < totalNrOfFiles){
int ii = in.readInt(); // File size
fileSize = (long)ii;
String filePath = Consts.SERVER_DRIVE + Consts.PTPP_FILETRANSFER;
filePath = filePath.concat(theBatch.getFileName(count));
File path = new File(filePath);
boolean resume = false;
//if the file exist. Skip if done or resume if not
if(path.exists()){
if(path.length() == fileSize){ // Does the file has same size
logger.info("File size same skipping file:" + theBatch.getFileName(count) );
count++;
out.writeUTF(Consts.SERVER_give_me_next);
continue; // file is OK don't upload it again
}else {
// Resume the upload
out.writeUTF(Consts.SERVER_file_exist);
out.writeLong(path.length());
resume = true;
fileSize = fileSize-path.length();
logger.info("Resume at : " + path.length() +
" Sending "+ fileSize +" bytes more");
}
}else
out.writeUTF("lets go");
byte[] buffer = new byte[1024];
// ***********************************
// RECEIVE FROM PHONE
// ***********************************
int size = 1024;
int val = 0;
bos = new BufferedOutputStream(new FileOutputStream(path,resume));
if(fileSize < size){
size = (int) fileSize;
}
while (fileSize >0) {
val = in.read(buffer, 0, size);
bos.write(buffer, 0, val);
fileSize -= val;
if (fileSize < size)
size = (int) fileSize;
}
bos.flush();
bos.close();
out.writeUTF("file received ok");
count++;
}
答案 0 :(得分:2)
发现错误,问题是我的错误。 不要再说了。
我发送的图片正在发送之前调整大小。
问题是在转移失败后简历被踢了 没有使用已调整大小的图片,而是使用原始的代码 如图所示,规模较大。
我现在已经设置了一个短暂的缓存来保存调整大小的临时图片。
鉴于应用程序的复杂性,我只是忘记了简历中的文件与原始文件不同。
答案 1 :(得分:2)
使用BufferedOutputStream,BufferedInputStream,您需要注意以下内容
这对我有用。
被修改
将sentRequestTime,receivedRequestTime,sentResponseTime,receivedResponseTime添加到数据包有效负载。对这些使用System.nanoTime(),在同一主机上运行您的服务器和客户端,使用ExecutorService为该服务器运行多个客户端,并为请求和响应数据包绘制您的(已接收),在excel图表上绘制时间延迟(一些csv格式)。在bufferedIOStream和afterIOStream之前执行此操作。您会很高兴地知道您的表现提升了100%。让我很高兴绘制该图表,大约需要45分钟。
我也听说使用自定义缓冲区可以进一步提高性能。
再次编辑 在我的情况下,我使用对象IOStreams,我已经向对象添加了4个长变量的有效负载,并在我从客户端发送数据包时初始化sentRequestTime,在服务器收到响应时初始化receivedRequestTime,依此类推响应从服务器到客户端。然后我找到接收和发送时间之间的差异,以找出响应和请求的延迟。小心在localhost上运行此测试。如果您在不同的硬件/设备之间运行它们,它们的实际时差可能会干扰您的测试结果。由于requestReceivedTime在服务器端加盖时间戳,requestSentTime在客户端加盖时间戳。换句话说,他们自己的当地时间被标记(显然)。并且这两个设备都运行完全相同的纳秒时间是不可能的。如果必须在不同设备之间运行它,请确保运行ntp(以保持时间同步)。那就是说,你在比较bufferedio之前和之后的表现(你真的不关心实际的时间延迟吗?),所以时间漂移应该不重要。在缓冲之前和缓冲之后比较一组结果是您的实际兴趣。
享受!!!