简体   繁体   中英

Java streams with EOFException

I wrote some client - server program, that shares data but at server side i got EOFException after reciving data. I tried to fix it on my own but it is hard to find own errors.

The error is caused by this line: Message command =(Message) serInputStream.readObject();

Here is some output from server:

 java.io.EOFException

at Java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2577)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1315)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at transfer.Serwerus.run(Serwerus.java:42)

Server code:

import java.io.*;
import java.net.*;

public class Serwerus implements Runnable
{
public InputStream is;
public FileOutputStream fos;
public BufferedOutputStream bos;
public ObjectOutputStream serOutputStream;
public ObjectInputStream serInputStream;
ServerSocket socket;
private String clientMessage, clientFileName;
private int clientFileSize;

public Serwerus()
{
    try
    {
        socket = new ServerSocket(6060);
        System.out.println("Server started....");
    }
    catch(IOException e)
    {
        System.err.println("Error: " + e);
        e.printStackTrace();
    }
}

@Override
public void run()
{
    try 
        {
            Socket sock = socket.accept();
            System.out.println("Client accepted");
            serOutputStream = new ObjectOutputStream(sock.getOutputStream());
            serInputStream = new ObjectInputStream(sock.getInputStream());
          while (true) 
          {
              Message command =(Message) serInputStream.readObject();
              System.out.println("after readObject");
              if (command.getCommand().startsWith("FileU")) 
              {
                  System.out.println("Name = " + command.getfileName() + ", size= " + command.getfileSize());
                  serOutputStream.writeObject(new Message("Bring", "", 0));
                  //ReciveData(socket, command.getfileName(), command.getfileSize());
              }
              else if(command.getCommand().startsWith("Wait"))
              {
                  System.out.println("hohoho");
                  ReciveData(sock, command.getfileName(), command.getfileSize());
              }
              else if(command.getCommand().startsWith("Quit"))
              {
                  System.exit(1);
              }
              else
              {
                  System.out.println("Unknow");
              }
          }
        }
        catch(ClassNotFoundException | IOException ex)
        {
            ex.printStackTrace();
        } 
        finally 
        {
            try 
            {
                serInputStream.close();
                serOutputStream.close();
                socket.close();
            } 
            catch (IOException e) 
            {
                System.err.println("Fallen on closing socket.\n Error: " + e);
            }
        }
}

public void SendData(Socket sock, String filePath) throws Exception
{
    File myFile = new File (filePath);
    System.out.println("File name = " + myFile.getName() + " File len = " + (int)myFile.length());
    byte [] mybytearray  = new byte [(int)myFile.length()];
    FileInputStream fis = new FileInputStream(myFile);
    BufferedInputStream bis = new BufferedInputStream(fis);
    bis.read(mybytearray,0,mybytearray.length);
    OutputStream os = sock.getOutputStream();
    System.out.println("Sending...");
    os.write(mybytearray,0,mybytearray.length);
    os.flush();
    sock.close();
    System.out.println("Sending finished");
}

public void ReciveData(Socket sock, String filePath, int fileSize)
{
    System.out.println("Recive in progress, filesize = " + fileSize);
    int bytesRead = 0, current = 0;
    byte[] array = new byte[fileSize];

    try 
    {

        is = sock.getInputStream();
        FileOutputStream fos = new FileOutputStream(filePath);
        bos = new BufferedOutputStream(fos);
        do
        {
            System.out.println(bytesRead);
            bytesRead = is.read(array);
            current += bytesRead;
        }
        while(bytesRead > -1);

        bos.write(array, 0 , current);
        bos.flush();
        bos.close();
        fos.close();
       // sock.close();
        System.out.println("Reciveing finished");
    } 
    catch (IOException ex) 
    {
        ex.printStackTrace();
    }
}

 public static void main (String [] args ) throws IOException 
 {
     new Thread(new Serwerus()).start(); 
 }
}

Client code:

import java.io.*;
import java.net.*;

public class Clientus implements Runnable
{
    InputStream is;
    FileOutputStream fos;
    BufferedOutputStream bos;
    ObjectOutputStream cliOutputStream;
    ObjectInputStream cliInputStream;
    Socket socket;
    File actFile;
    private String serverMessage, serverFileName;
    private int serverFileSize;

    public Clientus()
    {
        try 
        {
            socket = new Socket("localhost", 6060);
            cliOutputStream = new ObjectOutputStream(socket.getOutputStream());
            cliInputStream = new ObjectInputStream(socket.getInputStream());
            File file = new File(<filepath>);
            actFile = file;
        } 
        catch (Exception e) 
        {
            System.err.println("Error: " + e);
            e.printStackTrace();
        }
    }

    @Override
    public void run()
    {
        try 
            {   
                cliOutputStream.writeObject(new Message("FileU", actFile.getPath(), (int) actFile.length()));
                cliOutputStream.flush();
              //while (true) 
              //{
                  Message command =(Message) cliInputStream.readObject();
                  if (command.getCommand().startsWith("File")) 
                  {
                      String name = command.getfileName();
                      int size = command.getfileSize();
                      System.out.println("Name = " + command.getfileName() + ", size= " + command.getfileSize());
                      if(size != 0 && !"".equals(name))
                      {
                          //ReciveData(socket, 0);
                      }
                  }
                  else if(command.getCommand().startsWith("Bring"))
                  {
                      cliOutputStream.writeObject(new Message("Wait", "D:\\KP2\\Serwer\\dupa.txt",(int) actFile.length()));
                      cliOutputStream.flush();
                      try 
                      {
                          SendData(socket, actFile.getPath());
                          //this.socket.close();
                      } 
                      catch (Exception ex) 
                      {
                         System.err.println("Error with: SendData()");
                      }
                  }
                  else if(command.getCommand().startsWith("Quit"))
                  {
                      System.exit(1);
                  }
                  else
                  {
                      System.out.println("Command unknown");
                  }
              //}
            }
            catch(ClassNotFoundException | IOException ex)
            {
                ex.printStackTrace();
            } 
            finally 
            {
                try 
                {
                    socket.close();
                    cliOutputStream.close();
                    cliInputStream.close();
                } 
                catch (IOException e) 
                {
                    System.err.println("Fallen on closing socket.\n Error: " + e);
                }
            }
    }

    public void SendData(Socket sock, String filePath) throws Exception
    {
        byte [] mybytearray  = new byte [(int) new File(filePath).length()];
        FileInputStream fis = new FileInputStream(filePath);
        BufferedInputStream bis = new BufferedInputStream(fis);
        bis.read(mybytearray,0,mybytearray.length);
        OutputStream os = sock.getOutputStream();
        System.out.println("Sending...");
        os.write(mybytearray,0,mybytearray.length);
        fis.close();
        bis.close();
        os.close();
        System.out.println("Sending finished");
    }

    public void ReciveData(Socket sock, String fileName, int fileSize)
    {
        int bytesRead, current = 0;
        byte[] array = new byte[fileSize+1];
        try 
        {
            is = sock.getInputStream();
            fos = new FileOutputStream(<file_path>);

            bos = new BufferedOutputStream(fos);
            bytesRead = is.read(array,0,array.length);

            current = bytesRead;
            do
            {
                bytesRead = is.read(array, current, (array.length - current));
                if(bytesRead >= 0)
                    current += bytesRead;
            }
            while(bytesRead > -1);

            bos.write(array, 0 , current);
            bos.flush();

            long end = System.currentTimeMillis();

            //System.out.println("Send time: " + (end - start));
            bos.close();
            sock.close();
            System.out.println("Reciveing finished");
        } 
        catch (IOException ex) 
        {
            ex.printStackTrace();
        }
    }

    public static void main (String [] args ) throws IOException 
    {
        new Thread(new Clientus()).start();
    }
}

Can anyone help?

Your client may be disconnected after sending data and because your server is waiting for more data, the EOFException will occurr.

To fix this problem, you can add try-catch block to catching this exception when the client disconnects.

You are using both the ObjectOutputStream and the socket's own OutputStream to send data on, and you are getting out of sync. When you send the raw data directly over the socket you aren't sending the length first, so the receiver doesn't know how many bytes belong to this transmission. In fact it just reads everything until EOS, so next time you call ObjectInputStream.readObject() it naturally gets an EOFException. To fix this:

  1. Use the ObjectInputStream and ObjectOutputStream for everything .
  2. Before sending the file, send its length, via writeLong().
  3. At the receiver, when receiving the file, first get its length, via readLong(), then read exactly that many bytes from the ObjectInputStream and copy them to the file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM