我正在研究套接字文件发送方,它工作得很好,但是我无法用它发送大文件。总是遇到堆错误。然后我改变了客户端的代码,所以它会以块的形式发送文件。现在我可以发送大文件,但是有新问题。现在我收到空的小文件和较大的文件,例如视频无法播放。以下是发送文件的客户端代码:
public void send(File file) throws UnknownHostException, IOException {
// Create socket
hostIP = "localhost";
socket = new Socket(hostIP, 22333);
//Send file
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
OutputStream os = socket.getOutputStream();
//Sending size of file.
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(file.getName() + ":" + userName);
byte[] arr = new byte[1024];
try {
int len = 0;
while ((len = dis.read(arr)) != -1) {
dos.write(arr, 0, len);
}
} catch (IOException ex) {
ex.printStackTrace();
}
dos.flush();
socket.close();
}
这是服务器代码:
void start() throws IOException {
// Starts server on port.
serverSocket = new ServerSocket(port);
int bytesRead;
while (true) {
connection = serverSocket.accept();
in = connection.getInputStream();
clientData = new DataInputStream(in);
String[] data = clientData.readUTF().split(":");
String fileName = data[0];
String userName = data[1];
output = new FileOutputStream("C:/" + fileName);
long size = clientData.readLong();
byte[] buffer = new byte[1024];
// Build new file
while (size > 0 && (bytesRead = clientData.read(buffer, 0, (int) Math.min(buffer.length, size))) != -1) {
output.write(buffer, 0, bytesRead);
size -= bytesRead;
}
output.close();
}
}
答案 0 :(得分:3)
您无法将文件的长度写入客户端中的流:
long size = clientData.readLong();
因此服务器中的调用正在读取实际文件的前8个字节,谁知道该数量是多少。您不必从流中读取长度,因为您只写了一个文件。读完文件名和用户名后(不是很安全吗?)你可以直到EOF读取流。如果你想通过同一个打开的套接字发送多个文件,那么在阅读文件之前你需要知道它的长度。
此外,您的阅读缓冲区也很小。您应该至少为8192而不是1024.并且您希望将所有.close()放在finally块中,以确保您的服务器和客户端在有异常的情况下正确关闭。