为什么我的客户端关闭连接

时间:2013-07-27 22:07:55

标签: java sockets

您好我正在尝试学习如何通过套接字发送文件,所以我编写了两个非常简单的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)

事情是我没有关闭客户端中的任何套接字或流。为什么连接关闭?什么是同花顺呢?

2 个答案:

答案 0 :(得分:2)

我认为问题在于您尝试在客户端读取数据。

    byteLus = ois.read();

read()方法读取单个字节的数据!参考:the javadoc。但你似乎假设它(以某种方式)将多个字节读入buffer。 (或者其他什么。代码是错误的,并不是很明显你认为它应该做什么。)


但坦率地说,您的代码在客户端和服务器大小方面存在许多其他问题。一些问题如下:

  • 您应该(可能)不在read()上使用write(buffer)ObjectStream。您应该使用readObject()writeObject(obj) ...或使用DataInputStream / DataOutputStream

  • 您在服务器端读取文件的方式已损坏。您忽略了read调用的结果...它告诉您实际读入buffer的字节数。 (你不能假设只有当你接近文件末尾时,你才能获得更少的完整缓冲区。有些文件类型会定期给你不完整的读取...至少在某些平台上。)

  • 您没有关闭oosfos,因此可能存在数据未被刷新的问题。

  • byteLus < 1024测试令人费解......错误。

  • 如果文件不存在,在服务器上创建一个空文件的逻辑也让我感到厌烦。为什么???

答案 1 :(得分:0)

您的客户端在流结束时退出,退出该进程会关闭套接字。与此同时,您的服务器仍在发送,因为您的发送和接收代码完全处于极点。如@StephenC所述,您的代码还有许多其他问题。在Java中复制流的正确方法如下:

while ((count = in.read(buffer)) > 0)
{
   out.write(buffer, 0, count);
}

适用于任何大小的缓冲区&gt; 0.两端的代码相同,输入和输出不同。允许的语法变化:不是语义变异。