【发布时间】:2016-12-28 11:43:31
【问题描述】:
我正在尝试创建一个允许服务器和客户端相互发送文件的客户端/服务器程序。我创建了套接字,并将客户端连接到服务器。我现在正在同一台计算机上做这个。如果完善了,我会拿到另一台电脑上试试。
我的问题是文件传输成功但已损坏。收到的文件已损坏,但原件没问题。我遇到了套接字异常的问题,其中套接字在发送文件后不断重置,但我已经设法解决了这个问题。现在文件已发送,但尚未完成。
接收到的文件大小小于发送的文件大小,导致接收到的文件不工作。我通过网络发送了一个 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();
}
}
}
这是客户端类:
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 流发送的文件不是真正的文件,而只是一个文件对象,其中包含我要发送的文件的所有信息,而不是文件的二进制数据。
请问有人可以帮助我吗?为什么文件损坏或不完整?它被读取到最后(当 -1 时)返回,并且所有字节都被发送,但由于某种原因我无法解释,它最终小于原始文件的大小。
【问题讨论】:
标签: java sockets network-programming