通过socket完成zip文件的网络传输,但是传输过去会出现文件损坏。

斟一杯苦丁茶 2020-08-18 10:51:37
遇到的问题:我定义了一个字节数组data: byte[],用来暂存读取的字节数据, 当这个字节数组的大小设置为8192时传输的文件没有问题,8192字节应该是BufferedInputStream和BufferedOutputStream的默认缓存大小。当我吧这个字节数组的大小定义为非8192的数时传输的文件就会出现文件损坏,使用BufferedInputStream(socket.getInputStream(), databig);和BufferedOutputStream(socket.getOutputStream, databig);这两个构造函数时应该已经把默认的缓存大小更改了,但是传输依然出现文件损坏。到这里我就不知道是哪里出错了,如果是因为缓存大小与我定义的字节数组大小不合适的话,那在我修改默认缓存大小后应该能正常传输才对,但是并非如此。请求大神讲解一下,谢谢。


接收端代码:
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Receive {
final static String name = "E:\\2.zip";//接收文件储存位置
final static int port = 9999;
final static int databig = 8192;

public static void main(String[] args){
File file = new File(name);
byte[] data = new byte[databig];
long big = 0;
long count = 0;

try {
ServerSocket server = new ServerSocket(port);
System.out.println("等待发送端连接");
Socket socket = server.accept();
System.out.println("连接成功");
file.createNewFile();
FileOutputStream out = new FileOutputStream(file);
BufferedInputStream in = new BufferedInputStream(socket.getInputStream(), databig);
DataInputStream in2 = new DataInputStream(socket.getInputStream());
//接收文件大小
big = in2.readLong();
System.out.println(big);

while(true)
{
in.read(data, 0, data.length);
out.write(data, 0, data.length);
System.out.println((count*1.0/big*1.0)*100);
count+=databig;
}
}
catch (Exception e) {
System.out.println(e.toString());
}
System.out.println("接收成功");
}
}

发送端代码:
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.Socket;

public class Send {
final static String name = "E:\\2.zip";
final static String ip = "19.168.43.01";
final static int port = 9999;
final static int filebig = 8192;

public static void main(String[] args) {
File file = new File(name);
long big = file.length();
System.out.printf("文件总大小(Byte): ");
System.out.println(big);
byte[] data = new byte[filebig];
long count = 0;

try {
Socket socket = new Socket(ip, port);
FileInputStream in = new FileInputStream(file);
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream(), filebig);
DataOutputStream out2 = new DataOutputStream(socket.getOutputStream());
//发送文件大小
out2.writeLong(big);
out2.flush();

while(in.read(data, 0, data.length) != -1)
{
System.out.printf("发送文件百分比:");
System.out.println((count*1.0/big*1.0)*100);
out.write(data, 0, data.length);
out.flush();
count+=filebig;
}

System.out.println("发送成功");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
...全文
4753 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
自己定义个标准。分片传。另外最好加个结束标志。比如030201; 这样收到标志代表传完。 验证长度正确就对了。如何错误或者超时就说明断开。或者某一段没有接收到。
斟一杯苦丁茶 2020-08-18
  • 打赏
  • 举报
回复
引用 3 楼 tianfang的回复:
传输协议定义的不好。二进制传输没有控制字符(如\r\n EOF 控制),必须使用长度控制, 你没有在协议中定义传输长度,而客户端按照8192字节读取,当然有问题了。 你的传输协议,至少要传输一个协议头,最简单可以是4字节的文件长度,而且要约定,传输至少64字节(这个可以变),数据不足使用0补充。 你的发送端每次至少发送68字节(4字节头,只有文件长度,64字节最低数据)。接收端,首先读取68字节,分析长度,如果超过68字节,则继续读,不足就结束。
谢谢你的帮助,我找到原因了,是因为读取文件数据最后一次无法填满字节数组,导致全部补零,写入文件时没进行检查,然后新文件的内容最后面会出现一堆零,导致文件损坏。
tianfang 2020-08-18
  • 打赏
  • 举报
回复
传输协议定义的不好。二进制传输没有控制字符(如\r\n EOF 控制),必须使用长度控制, 你没有在协议中定义传输长度,而客户端按照8192字节读取,当然有问题了。 你的传输协议,至少要传输一个协议头,最简单可以是4字节的文件长度,而且要约定,传输至少64字节(这个可以变),数据不足使用0补充。 你的发送端每次至少发送68字节(4字节头,只有文件长度,64字节最低数据)。接收端,首先读取68字节,分析长度,如果超过68字节,则继续读,不足就结束。
斟一杯苦丁茶 2020-08-18
  • 打赏
  • 举报
回复
引用 1 楼 Farmermark993的回复:
原因在于包数据没有接收完成,进程已经断开了,你看看损坏的包是不是小于之前的包
你好,可是为什么将字节数组设置为8192字节就可以完全接收
Forevermark993 2020-08-18
  • 打赏
  • 举报
回复
原因在于包数据没有接收完成,进程已经断开了,你看看损坏的包是不是小于之前的包

62,625

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧