【问题标题】:why IOException is triggered after receiving file from server (Socket programming) [duplicate]为什么从服务器接收文件后触发IOException(套接字编程)[重复]
【发布时间】:2016-06-25 20:43:00
【问题描述】:

这是我正在解决的问题。 1)有一台服务器和一台客户端。 2)服务器与客户端连接。 3)服务器发送一个文件(.mp3)。 4)发送文件后,它会发送一些额外的字符串数据。

文件发送后我收到 IOException,所以我的客户端没有读取额外的字符串数据。WHYYYYYYYY?

这是服务器代码

 public class server {

ServerSocket server;
Socket socket;
FileInputStream fis;
FileOutputStream fos;
DataInputStream dis;
DataOutputStream dos;

public static void main(String args[])
{       
    server s=new server();
    s.connnect();
    s.init();
    s.send("f://song.mp3");     
}

public void connnect()
{
    try {
        server=new ServerSocket(8080);
        socket =server.accept();
    } catch (IOException e) {

    }       
}

public void init()
{
    try {
        dis=new DataInputStream(socket.getInputStream());
        dos=new DataOutputStream(socket.getOutputStream());
    } catch (IOException e) {
        e.printStackTrace();
    }       
}

public void send(String name)
{
    File f=new File(name);
    try {
        fis=new FileInputStream(f);
    } catch (FileNotFoundException e) {

        e.printStackTrace();
    }

    String nam=f.getName();

    try {
        dos.writeUTF(nam);
        System.out.println("header sent");

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    byte[] buffer=new byte[1024];

    int read=-1;

    try {
        while((read=fis.read(buffer))!=-1)
        {
            dos.write(buffer, 0, read);
        }

        System.out.println("file "+name+" sent");

        dos.writeUTF("this is the msg which is not received by client because of IOexception in client side");

    } 
    catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }               
}

}

客户端代码

 public class client {


ServerSocket server;
Socket socket;
FileInputStream fis;
FileOutputStream fos;
DataInputStream dis;
DataOutputStream dos;

public static void main(String args[])
{
    client s=new client();
    s.connect();
    s.init();
    try {           
    s.rec(s.dis.readUTF());      ///this the name of the String         
    } catch (IOException e) {

    }       
}

public void connect()
{
    try {
        socket=new Socket("127.0.0.1",8080);
        System.out.println("connected with server");
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }       
}

public void init()
{
    try {
        dis=new DataInputStream(socket.getInputStream());
        dos=new DataOutputStream(socket.getOutputStream());
    } catch (IOException e) {
        System.out.println("IO EXception in streams");
        e.printStackTrace();
    }       
}

public void rec(String filename)
{
    File f=new File("f://abc");
    f.mkdirs();     
    File temp=new File(f,filename);     
    try {
        fos=new FileOutputStream(temp);
    } catch (FileNotFoundException e) {

        e.printStackTrace();
    }

    byte[] buffer=new byte[1024];
    int read=-1;

    System.out.println("started reading file"+filename);

    try {           
        while((read=dis.read(buffer))!=-1)
        {
            fos.write(buffer, 0, read);
        }

        String FINAL_MSG=dis.readUTF();
        System.out.println("ended "+FINAL_MSG);

    } 
    catch (IOException e) {
        System.out.println("why IO exception?");
    }       
}

public void sendFile(String name)
{
    File f=new File("f://abc");
    f.mkdirs();

    File temp=new File(f,name);

    try {
        fos=new FileOutputStream(temp);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    byte[] buffer=new byte[1024];
    int read=-1;

    try {
        while((read=dis.read(buffer))!=-1)
        {
            fos.write(buffer, 0, read);
        }
    } 
    catch(SocketException e)
    {
        System.out.println(name+" has end"+" "+(socket==null));

    }
    catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }       
}   

}

我想读取附加的字符串数据(FINAL_MSG)。怎么可能?

服务器输出

header sent     
file f://song.mp3 sent       
Final MSG is sent from server side 

客户端输出

connected with server    
started reading filesong.mp3     

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.DataOutputStream.write(Unknown Source)
at s1.send(s1.java:87) at s1.main(s1.java:30)

为什么会出现 IO 异常?

【问题讨论】:

  • 添加 IOException 的完整堆栈跟踪。
  • 不,我的问题是为什么会去 catch(IOException){System.out.println("why IO exception"}。
  • @flkes 它是 .mp3 文件,它在文件末尾给出 -1。
  • 您的问题很可能是读取“文件数据”的客户端代码也最终读取了您的最终消息并将其保存到文件中。因此,当您尝试读取客户端中的最终消息时,您现在处于“流结束”状态。
  • 正如@Quintium 所说,您正在消耗整个流。您需要发送一个控件来设置长度。发送一个您在另一端读取的长值,以便您最终只读取文件部分。然后将流的其余部分作为字符串完成。

标签: java sockets ioexception


【解决方案1】:

您的服务器程序在客户端读取所有导致 IO 异常的数据之前终止。

您的服务器程序正在发送一个 mp3 文件,然后打印发送的消息文件,再次通过套接字写入数据,然后由于无事可做,它被终止/结束,因此服务器套接字关闭,这反过来又导致 IO 异常在客户端程序中。

【讨论】:

  • 在客户端获取 IOException
  • 这就是我在回答中提到的,因为服务器已经消失,你在客户端/客户端程序中遇到了 IO 异常。这就是 TCP 的工作原理。您的服务器程序正在结束。我自己运行了你的代码。如果您想验证我在说什么,为什么不在您遇到异常的客户端程序中放置一个断点。当服务器端未运行时,您将看到客户端何时发生异常。
  • 我在 while ((read=dis.read(buffer))!=-1) { fos.write(buffer, 0, read); } 和 FINAL_MSG = dis.readUTF();
  • @SumitRathi 服务器正在结束的证据为零。我们只知道它已经关闭了连接。
  • @RohitSingh : 请在 Scanner sc = new Scanner(System.in); 中添加以下行字符串结束 = sc.next();调用 send 方法后服务器程序的 main 方法。您会注意到添加这些行后您不会收到任何 IO 异常,因为现在服务器正在等待一些输入。通过这种方式,您将能够验证我在回答中提到的内容,即您的服务器程序在客户端可以读取所有数据之前结束。验证后将 -1 转换为 +1 :)
【解决方案2】:

当您仍在写入时,对等方已经关闭了连接。换句话说,应用程序协议错误。

在这种情况下,服务器不会关闭接受的套接字,而只是退出线程。

【讨论】:

  • 我该如何解决?任何建议
  • 调试您的应用程序。对等方不应该关闭,或者您不应该仍然发送。
猜你喜欢
  • 2021-03-30
  • 2014-12-05
  • 2015-01-17
  • 2011-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-25
相关资源
最近更新 更多