您好我正在尝试学习如何通过套接字发送文件,所以我编写了两个非常简单的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)
事情是我没有关闭客户端中的任何套接字或流。为什么连接关闭?什么是同花顺呢?
答案 0 :(得分:2)
我认为问题在于您尝试在客户端读取数据。
byteLus = ois.read();
read()
方法读取单个字节的数据!参考:the javadoc。但你似乎假设它(以某种方式)将多个字节读入buffer
。 (或者其他什么。代码是错误的,并不是很明显你认为它应该做什么。)
但坦率地说,您的代码在客户端和服务器大小方面存在许多其他问题。一些问题如下:
您应该(可能)不在read()
上使用write(buffer)
或ObjectStream
。您应该使用readObject()
和writeObject(obj)
...或使用DataInputStream
/ DataOutputStream
。
您在服务器端读取文件的方式已损坏。您忽略了read
调用的结果...它告诉您实际读入buffer
的字节数。 (你不能假设只有当你接近文件末尾时,你才能获得更少的完整缓冲区。有些文件类型会定期给你不完整的读取...至少在某些平台上。)
您没有关闭oos
或fos
,因此可能存在数据未被刷新的问题。
byteLus < 1024
测试令人费解......错误。
如果文件不存在,在服务器上创建一个空文件的逻辑也让我感到厌烦。为什么???
答案 1 :(得分:0)
您的客户端在流结束时退出,退出该进程会关闭套接字。与此同时,您的服务器仍在发送,因为您的发送和接收代码完全处于极点。如@StephenC所述,您的代码还有许多其他问题。在Java中复制流的正确方法如下:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
适用于任何大小的缓冲区&gt; 0.两端的代码相同,输入和输出不同。允许的语法变化:不是语义变异。