我试图创建一个客户端/服务器程序,允许服务器和客户端向对方发送文件。我创建了套接字,并将客户端连接到服务器。我现在正在为这台计算机做同一台计算机。如果它完善了,我会把它带到另一台电脑上试试。通过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)被返回时,并且所有的字节被发送,但由于某些原因,我不能解释,它最终小于原始文件的大小。