嗨,我正在尝试学习如何通过套接字发送文件,因此我编写了两个非常简单的 java 类:客户端和服务器,它们在这里
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main (String[] args)throws IOException{
File f = new File("J:\\RepServer\\zebi.txt");
if(!f.exists()){
f.createNewFile();
}
//System.out.print(f.exists()+f.getName());
ServerSocket ss = new ServerSocket(1000);
Socket s = ss.accept();
FileInputStream fileStream = new FileInputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
oos.writeObject("Envoi Fichier|"+f.getName()+"|"+f.length());
byte[] buffer = new byte[150000];
long completed =0;
while(completed <= f.length()){
fileStream.read(buffer);
oos.write(buffer);
completed += 150000;
}
oos.writeObject("Envoi termine");
fileStream.close();
}
}
和客户端类
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
public class Client {
/**
* @param args
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
new File("J:\\RepClient\\").mkdir();
Socket s = new Socket("127.0.0.1",1000);
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
String fileName = ((String)ois.readObject()).split("|")[1].trim();
FileOutputStream fos = new FileOutputStream("J:\\RepClient\\"+fileName);
byte[] buffer = new byte[200000];
int byteLus = 0, compteur = 0;
while(byteLus >= 0){
byteLus = ois.read();
if(byteLus >= 0){
fos.write(buffer, 0, byteLus);
compteur += byteLus;
System.out.println("Le nombre de bytes lus est :"+byteLus);
}
if(byteLus < 1024){
fos.flush();
break;
}
}
}
}
所以我启动服务器,然后启动客户端,服务器将文件发送到客户端,客户端创建文件但为空,因为在服务器写入之前会发生此异常。
Exception in thread "main" java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at java.io.ObjectOutputStream$BlockDataOutputStream.writeBlockHeader(Unknown Source)
at java.io.ObjectOutputStream$BlockDataOutputStream.write(Unknown Source)
at java.io.ObjectOutputStream.write(Unknown Source)
at Server.main(Server.java:25)
问题是我没有关闭客户端中的任何套接字或流。那么为什么连接会关闭呢?顺便说一句,flush 在做什么?
最佳答案
我认为问题在于您尝试在客户端读取数据的方式。
byteLus = ois.read();
read()
方法读取单个字节的数据!引用:the javadoc 。但您似乎假设它会(以某种方式)将多个字节读入 buffer
。 (或者其他什么。代码是如此错误,你认为它应该做什么并不明显!)
但坦率地说,您的代码还存在许多其他问题,无论是在客户端还是在服务器大小上。部分问题如下:
您不应该(可能)使用
read()
或write(buffer)
在ObjectStream
上。您应该使用readObject()
和writeObject(obj)
...或使用DataInputStream
/DataOutputStream
.您在服务器端读取文件的方式已损坏。您忽略了
read
的结果调用 ... 告诉您实际读入buffer
的字节数。 (您不能假设唯一一次您获得的缓冲区少于完整缓冲区是当您接近文件末尾时。某些文件类型会定期给您提供不完整的读取......至少在某些平台上。)您没有关闭
oos
或fos
所以可能会出现数据没有刷新的问题。byteLus < 1024
测试令人费解……而且是错误的。如果文件不存在,则在服务器上创建空文件的逻辑(也)让我无法理解。为什么???
关于java - 为什么我的客户端关闭连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17902927/