gpt4 book ai didi

java - 使用 Java 套接字发送文件,丢失数据

转载 作者:可可西里 更新时间:2023-11-01 02:35:06 24 4
gpt4 key购买 nike

我正在尝试使用 Java 中的套接字将文件从客户端发送到服务器。当我在同一台机器上测试时它工作正常,但是当我在不同机器上测试时,我丢失了大量数据,导致文件损坏。如果我尝试发送一个非常小的文件(<20 字节),它甚至不会到达服务器 while 循环内的 println。

这是我的代码:

服务器.java

package edu.mst.cs.sensorreceiver;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
private static final int PORT = 51111;
private static final int CHUNK_SIZE = 1024;
private static final File _downloadDir = new File("downloads/");

public static void main(String[] args) {
if (!_downloadDir.exists()) {
if (!_downloadDir.mkdirs()) {
System.err.println("Error: Could not create download directory");
}
}

Socket socket = null;
try {
ServerSocket server = new ServerSocket(PORT);

while (true) {
System.out.println("Waiting for connection...");
socket = server.accept();

BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

String name = in.readLine();
File file = new File(_downloadDir, name);

String size = in.readLine();
int fileSize;
try {
fileSize = Integer.parseInt(size);
} catch (NumberFormatException e) {
System.err.println("Error: Malformed file size:" + size);
e.printStackTrace();
return;
}

System.out.println("Saving " + file + " from user... (" + fileSize + " bytes)");
saveFile(file, socket.getInputStream());
System.out.println("Finished downloading " + file + " from user.");
if (file.length() != fileSize) {
System.err.println("Error: file incomplete");
}
}

} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

private static void saveFile(File file, InputStream inStream) {
FileOutputStream fileOut = null;
try {
fileOut = new FileOutputStream(file);

byte[] buffer = new byte[CHUNK_SIZE];
int bytesRead;
int pos = 0;
while ((bytesRead = inStream.read(buffer, 0, CHUNK_SIZE)) >= 0) {
pos += bytesRead;
System.out.println(pos + " bytes (" + bytesRead + " bytes read)");
fileOut.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileOut != null) {
try {
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("Finished, filesize = " + file.length());
}
}

客户端.java

package edu.mst.cs.sensorreceiver;

import java.io.*;
import java.net.Socket;

public class Client {
private static final String HOSTNAME = "131.151.163.153";
private static final int PORT = 51111;
private static final int CHUNK_SIZE = 1024;

public static void main(String[] args) {
sendFile(args[0]);
}

private static void sendFile(String path) {
if (path == null) {
throw new NullPointerException("Path is null");
}

File file = new File(path);
Socket socket = null;
try {
System.out.println("Connecting to server...");
socket = new Socket(HOSTNAME, PORT);
System.out.println("Connected to server at " + socket.getInetAddress());

PrintStream out = new PrintStream(socket.getOutputStream(), true);

out.println(file.getName());
out.println(file.length());

System.out.println("Sending " + file.getName() + " (" + file.length() + " bytes) to server...");
writeFile(file, socket.getOutputStream());
System.out.println("Finished sending " + file.getName() + " to server");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

private static void writeFile(File file, OutputStream outStream) {
FileInputStream reader = null;
try {
reader = new FileInputStream(file);
byte[] buffer = new byte[CHUNK_SIZE];
int pos = 0;
int bytesRead;
while ((bytesRead = reader.read(buffer, 0, CHUNK_SIZE)) >= 0) {
outStream.write(buffer, 0, bytesRead);
outStream.flush();
pos += bytesRead;
System.out.println(pos + " bytes (" + bytesRead + " bytes read)");
}
} catch (IndexOutOfBoundsException e) {
System.err.println("Error while reading file");
e.printStackTrace();
} catch (IOException e) {
System.err.println("Error while writing " + file.toString() + " to output stream");
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

我已经为此工作了几个小时,但几乎没有取得任何进展。我以为我对从流中读取/写入的工作原理有很好的理解,但显然我在这里遗漏了一些东西。

同样,当我从同一台机器发送和接收时,一切都完美无缺。但是,如果我尝试在两台计算机之间发送文件,即使两台计算机位于同一局域网中,我也会丢失大量已发送的数据。

有人能解决我的问题吗?我已经尝试了所有我能想到的方法。

最佳答案

您似乎在混合分块数据和面向行的操作。我建议你使用 DataInputStream在服务器上,还有一个 DataOutputStream .从客户端开始,类似

private static void sendFile(String path) {
if (path == null) {
throw new NullPointerException("Path is null");
}

File file = new File(path);
Socket socket = null;
try {
System.out.println("Connecting to server...");
socket = new Socket(HOSTNAME, PORT);
System.out.println("Connected to server at "
+ socket.getInetAddress());

try (DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream()));) {
dos.writeUTF(file.getName());
dos.writeLong(file.length());

System.out.println("Sending " + file.getName() + " ("
+ file.length() + " bytes) to server...");
writeFile(file, dos);
System.out.println("Finished sending " + file.getName()
+ " to server");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

然后在服务器上

socket = server.accept();

DataInputStream dis = new DataInputStream(socket.getInputStream());
String name = dis.readUTF();
File file = new File(_downloadDir, name);
long fileSize = dis.readLong();
System.out.println("Saving " + file + " from user... ("
+ fileSize + " bytes)");

关于java - 使用 Java 套接字发送文件,丢失数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26569288/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com