通过java套接字发送文件时出错
我在通过socket java发送文件时遇到问题。代码有时有效,有时无效。我在这两个测试中都测试了while块,似乎代码正在发送所有字节,但服务器没有接收(但即使在这个测试中,文件也正确发送)。在这种情况下,服务器停止接收数据。所有文件的大小约为150Kb。我正在使用端口9191 服务器:通过java套接字发送文件时出错,java,file,sockets,send,Java,File,Sockets,Send,我在通过socket java发送文件时遇到问题。代码有时有效,有时无效。我在这两个测试中都测试了while块,似乎代码正在发送所有字节,但服务器没有接收(但即使在这个测试中,文件也正确发送)。在这种情况下,服务器停止接收数据。所有文件的大小约为150Kb。我正在使用端口9191 服务器: while (true) { try { Socket socket = ss.accept(); ObjectInputStream in =
while (true) {
try {
Socket socket = ss.accept();
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
String fileName = in.readUTF();
FileOutputStream fos = new FileOutputStream(destinationPath + fileName);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) >= 0) {
fos.write(buf, 0, len);
}
fos.flush();
} catch (Exception ex) {
ex.printStackTrace();
}
}
客户:
try {
Socket socket = new Socket(host, port);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
out.writeUTF(file.getName());
out.writeLong(file.length());
FileInputStream in = new FileInputStream(file);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) >= 0) {
out.write(buf, 0, len);
}
out.close();
socket.close();
} catch (Exception e) {
throw e;
}
首先,您应该分别用
DataInputStream
和DataOutputStream
替换ObjectInputStream
。您没有序列化java对象,因此使用用于此目的的流类毫无意义
第二,在客户端发送文件长度,但不在服务器中专门读取。而是将其添加到文件的开头。在您所说的客户端上
out.writeUTF(file.getName());
out.writeLong(file.length());
但是在服务器上你说
String fileName = in.readUTF();
FileOutputStream fos = new FileOutputStream(destinationPath + fileName);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) >= 0) {
fos.write(buf, 0, len);
}
fos.flush();
您没有读取文件长度。您需要确保读取所有发送的字节(否则您的文件将被损坏)。另外,不要忘记close()
FileOutputStream(或者使用a为您关闭它)。大概
String fileName = in.readUTF();
try (FileOutputStream fos = new FileOutputStream(destinationPath
+ fileName)) {
long size = in.readLong();
byte[] buf = new byte[1024];
long total = 0;
int len;
while ((len = in.read(buf)) >= 0) {
fos.write(buf, 0, len);
total += len;
}
if (total != size) {
System.err.printf("Expected %d bytes, but received %d bytes%n",
size, total);
}
}
我做了更改,并意识到它发送了1个文件,服务器上代码的第二个(相同或不同)文件进入“while((len=in.read(buf))>=0{”中的无限循环,因为我在块后面放了一个println,它不会在第二次显示。@Marcelo如果您想从客户端向服务器发送多个文件,我建议首先发送一个int,告诉服务器需要多少文件。然后每个文件都从文件名开始,然后是大小,然后是大小字节。在服务器上读取文件na我,它是大小,然后将大小字节从流复制到文件并重复,直到文件用完。事实上,在localhost中工作,但在ubuntu服务器中远程不工作。我清除iptables规则,什么都不做。在这种情况下,我发送一个文件,几秒钟后发送另一个文件。远程尝试时会出现什么错误?什么都不做。它会在内部停止在while循环中,什么也不做。我将消息放在内部,它突然停止显示消息。我做了更改,并意识到它发送了一个文件,服务器上代码的第二个(相同或不同)文件进入无限循环“while((len=in.read(buf))>=0){”,因为我在块后面放了一个println,它不会在第二次显示。请确保您正在发送另一个文件…上面的代码发送一个文件(不是多个文件-客户端发出调用
socket.close();
)事实上,在localhost中可以工作,但在ubuntu服务器中不能。我清除了iptables规则,什么也没有。在这种情况下,我发送了一个文件,几秒钟后,发送了另一个文件,再次调用SocketClient。再次调用SocketClient是什么意思?一旦调用socket.close()
如果不重新连接,则无法使用套接字
。类似地,一旦调用out.close()
,如果不重新连接,则无法使用socket.getOutputStream()中的输出流.因此,每次我想发送文件时都会实例化SocketClient。在本例中,我在循环中调用SocketClient N次。我认为在本例中,在SocketClient中调用socket.close()不是问题。