遇到的問題:我定義了一個位元組陣列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();
}
}
}
uj5u.com熱心網友回復:
原因在于包資料沒有接收完成,行程已經斷開了,你看看損壞的包是不是小于之前的包uj5u.com熱心網友回復:
你好,可是為什么將位元組陣列設定為8192位元組就可以完全接收
uj5u.com熱心網友回復:
傳輸協議定義的不好。二進制傳輸沒有控制字符(如\r\n EOF 控制),必須使用長度控制,你沒有在協議中定義傳輸長度,而客戶端按照8192位元組讀取,當然有問題了。
你的傳輸協議,至少要傳輸一個協議頭,最簡單可以是4位元組的檔案長度,而且要約定,傳輸至少64位元組(這個可以變),資料不足使用0補充。
你的發送端每次至少發送68位元組(4位元組頭,只有檔案長度,64位元組最低資料)。接收端,首先讀取68位元組,分析長度,如果超過68位元組,則繼續讀,不足就結束。
uj5u.com熱心網友回復:
謝謝你的幫助,我找到原因了,是因為讀取檔案資料最后一次無法填滿位元組陣列,導致全部補零,寫入檔案時沒進行檢查,然后新檔案的內容最后面會出現一堆零,導致檔案損壞。
uj5u.com熱心網友回復:
自己定義個標準。分片傳。另外最好加個結束標志。比如030201;這樣收到標志代表傳完。
驗證長度正確就對了。如何錯誤或者超時就說明斷開。或者某一段沒有接收到。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/17706.html
標籤:Java SE
上一篇:springboot 配置報錯
