我試圖創建一個客戶端/服務器程序,允許服務器和客戶端向對方發送文件。我創建了套接字,並將客戶端連接到服務器。我現在正在爲這臺計算機做同一臺計算機。如果它完善了,我會把它帶到另一臺電腦上試試。通過java socket編程共享的文件最終在接收端被破壞
我的問題是,文件傳輸成功,但它已損壞。收到的文件已損壞,但原文沒問題。我發生套接字異常的問題,在套接字發送文件後不斷重置,但我設法解決這個問題。現在文件已發送,但尚未完成。
收到的文件大小小於發送文件的大小,這導致收到的文件無法正常工作。我通過網絡發送了一個pdf文件。原文約爲695kb,但收到的文件爲688kb,導致文件被損壞。我也嘗試發送視頻,並得到相同的結果。接收到的文件比發送的文件小。
我檢查了程序,但是我看不到問題來自哪裏。 我試圖實現的發送方法是零拷貝方法,其中來自文件的數據直接發送到套接字,從它直接讀取到文件的位置。在將它發送到輸出流之前,我沒有使用存儲在緩衝區中的其他方法。這是因爲我想能夠使用該程序發送大文件。大文件將填滿java堆內存,此外此方法更快。
緩衝方法:
....
File file = new File("path to file);
BufferedInputStream = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
byte[] buf = new byte[length];
in.read(buf, 0, buf.length);
out.write(buf, 0, buf.length);
....
我沒有用這個緩衝區方法。這是我的代碼。這是文件服務器
import java.io.*;
import java.net.*;
import javax.swing.JFileChooser;
public class ShareServer {
public static void main(String args[]) {
int port = 4991;
ServerSocket server;
Socket socket = null;
BufferedInputStream in = null;
BufferedOutputStream out = null;
try {
server = new ServerSocket(port);
System.out.println("Waiting for connection request..");
socket = server.accept();
System.out.println("Connected to " + socket.getInetAddress().getHostName());
JFileChooser fc = new JFileChooser();
File file = null;
if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
file = fc.getSelectedFile();
// send out the reference of the file using writeObject() method
new ObjectOutputStream(socket.getOutputStream()).writeObject(file);
in = new BufferedInputStream(new FileInputStream(file));
out = new BufferedOutputStream(socket.getOutputStream());
// send file
int b = 1;
while (b != -1){
b = in.read();
out.write(b);
}
System.out.println(file.getName() + " has been sent successfully!");
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
try {
in.close();
out.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
這裏是Client類:
import java.io.*;
import java.net.*;
import javax.swing.JOptionPane;
public class ShareClient {
public ShareClient() {
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
String host = InetAddress.getLocalHost().getHostAddress();
Socket socket = new Socket(host, 4991);
System.out.println("Connected to " + host);
// receive the file object. this does not contain the file data
File refFile = (File) new ObjectInputStream(socket.getInputStream()).readObject();
System.out.println("File to receive " + refFile.getName());
// create a new file based on the refFile
File newFile = new File(System.getProperty("user.home") + "/desktop/ReceivedFiles", refFile.getName());
BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(newFile));
System.out.println("Receiving file now...");
int b;
while ((b = in.read()) != -1)
out.write(b);
System.out.println("File has been received successfully!");
socket.close();
}
}
的服務器和客戶端類的成功運行沒有任何異常,並且該文件被髮送,但它已損壞。它是不完整的。 請注意,通過ObjectInput和ObjectOutput流發送的文件不是真實文件,而只是一個文件對象,它具有我要發送的filie的所有信息,但不包含文件的二進制數據。
請問有人可以幫我嗎?爲什麼文件損壞或不完整?它被讀到最後(當-1)被返回時,並且所有的字節被髮送,但由於某些原因,我不能解釋,它最終小於原始文件的大小。