2

I get an EOFException when I'm trying to send an object through a server socket in Java.

This is the code on the sending part:

public static void sendObject(Object Object, InetAddress IP, int Port){
    try{
        Socket receivingSocket = new Socket(IP, Port);
        OutputStream OS = receivingSocket.getOutputStream();
        ObjectOutputStream OOS = new ObjectOutputStream(OS);

        OOS.writeObject(Object);
        OOS.close();
        OS.close();
        receivingSocket.close();
    }
    catch(Exception e){
        System.err.println("Failed to send object to: " + IP + " on port: " + Port);
        System.err.println(e);
    }
}

I tried casting the object to the specific object and that didn't work. The problem actually shows up on the receiving side which looks like this:

public Downloader(int PortStart, int PortStop, Loading_State loading_state){
    this.loading_state = loading_state;

    for(int i = PortStart;i<PortStop;i++){
        try {
            SS = new ServerSocket(i);
            break;
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public void run(){
    try {
        S = SS.accept();
        IS = S.getInputStream();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    while(!destroy){
        while(active){
            try {
                OIS = new ObjectInputStream(IS);
                Character Char = (Character)OIS.readObject();
                loading_state.setChar(Char);
                pause();
            }
            catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

So when I initiate the download the console immediatly spits out:

java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at input_output.network.Downloader.run(Downloader.java:68)

Edit: The object does implement Serializeable

public class Character implements Serializable{
private static final long serialVersionUID = -6390272842934614484L;

BIG EDIT!:

I dont know why or how but I think the download works BUT now it can't cast the received object to my object!

Character Char = (Character)OIS.readObject();
java.lang.ClassCastException: server.database.account.Character cannot be cast to database.Character

Any ideas why?

user207421
  • 305,947
  • 44
  • 307
  • 483
David Ekermann
  • 87
  • 3
  • 13

4 Answers4

1

Is your object serializable? The object should implement serializable interface:

class MyClass implements Serializable {
} 
acdcjunior
  • 132,397
  • 37
  • 331
  • 304
  • 1
    Welcome to Stack Overflow! This is really a comment, not an answer. With a bit more rep, [you will be able to post comments](http://stackoverflow.com/privileges/comment). For the moment I've added the comment for you, and I'm flagging this post for deletion. – Joachim Sauer Apr 16 '13 at 11:43
  • If this was the problem he would get a NotSerializableException when sending. This is an EOFException when receiving. -1 – user207421 Apr 16 '13 at 11:56
0

You're only sending one object, yet you are looping expecting to read multiple objects. That doesn't make sense. Either send more objects or only read one. If you send and read multiple objects you will always get an EOFException when you go to read one more than was sent.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I should have explained more. After receiving an object it pauses the downloader before transfering the object and then resuming to download another object. – David Ekermann Apr 16 '13 at 12:01
  • The code you posted has the deficiency I described. Your new code has others. You need to start a new thread per accepted connection, for a start. – user207421 Apr 17 '13 at 00:02
-1

Two things,

  1. While loop should cover entire run method( i believe so seeing the code)
  2. Since its infinite loop, which could collect empty inputs , you should handle that as well.

    public void run(){

    while(!destroy){
    
        while(active){
            try{
                S = SS.accept();
                IS = S.getInputStream();
                if(IS!=null && IS.available()>0){
                    OIS = new ObjectInputStream(IS);
                    Character Char = (Character)OIS.readObject();
                    loading_state.setChar(Char);
                    pause();
                }
            }
            catch(Exception e){  ..}
        }
    }
    

    }

Satheesh Cheveri
  • 3,621
  • 3
  • 27
  • 46
  • if(IS!=null && IS.available()>0) Was only true once in quite a few times and it threw out an exception – David Ekermann Apr 16 '13 at 12:19
  • There are very few correct uses of available(), and this is not one of them. All this does is ignore streams that haven't written an object *yet.* and leak them too. If the client sends something later it will be lost. Also 'IS' can never be null so testing for it is pointless. -1 – user207421 Apr 16 '13 at 23:58
-1

I solved it!

First problem was that I sent a request at the same time as I started the thread to download (I think) so what I did was I send the request a little bit later and suddenly the EOF facepalm exception was gone...

Now I had the convert exception left and the problem there was that I had to have the class (object) character in the exact same package hierarchy as the sender cause java is stupid.

Thanks for the help!

David Ekermann
  • 87
  • 3
  • 13
  • EOFException is not affected by changing the timing. You must have fixed something else, such as the issue noted in my answer. – user207421 Apr 17 '13 at 00:03