-2

I use RMI and socket to transfer files between a client set. The problem is when running the code below sometimes i get this exception in client side :

java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2671)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:3146)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:858)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:354)
at javafxcyberwind.serverSocket.run(serverSocket.java:38)
at java.lang.Thread.run(Thread.java:748)

This is a sample of my code, the exceptions are in comment lines :

Client :

Server_MethodsPEER S = (Server_MethodsPEER) Naming.lookup("rmi://" + ip + ":" + port + "/" + email);
Server_Methods R = S.peer();
R.uploadToServer(fileName);
Socket s = new Socket(ip, R.getServerSocketPort());
File fres = new File(crep + fileName);
FileInputStream inf = new FileInputStream(fres);
ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
byte buf[] = new byte[1024];
int nn;
while ((nn = inf.read(buf)) != -1) {
    out.write(buf, 0, nn);
}
out.close();
inf.close();
s.close();
fres.delete();

Server :

public class serverSocket implements Runnable {

private final ServerSocket socketserver;
private Socket socket;
private final String ff;
private final String rp;

public serverSocket(ServerSocket s, String file, String rep) {
    socketserver = s;
    ff = file;
    rp = rep;
}

@Override
public void run() {
    try {
        socket = socketserver.accept();
        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());//EOFException here
        FileOutputStream out = new FileOutputStream(new File(rp + ff));
        byte buf[] = new byte[1024];
        int n;
        while ((n = in.read(buf)) != -1) {
            out.write(buf, 0, n);
        }
        in.close();
        out.close();
        socket.close();
        socketserver.close();
    } catch (IOException e) {
        System.err.println("socket err");
    }
}
}

//ServerIMPL
ServerSocket sv;

public void uploadToServer(String fileName) throws RemoteException {
    try {
        sv = new ServerSocket(0);
    } catch (IOException ex) {
        Logger.getLogger(Cloud_ServeurIMPL.class.getName()).log(Level.SEVERE, null, ex);
    }
    Thread t = new Thread(new serverSocket(sv, file, crep));
    t.start();

    Client3_MethodsPEER M = (Client3_MethodsPEER) Naming.lookup("rmi://" + ip + ":" + port + "/" + email);
    Client3_Methods U = M.peer();
    U.uploadToServer(fileName);
    Socket s = new Socket(ip, U.getServerSocketPort());
    File fres = new File(crep + fileName);
    FileInputStream inf = new FileInputStream(fres);
    ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
    byte buf[] = new byte[1024];
    int nn;
    while ((nn = inf.read(buf)) != -1) {
        out.write(buf, 0, nn);
    }
    out.close();
    inf.close();
    s.close();
    fres.delete();
    U.operation();//FileNotFoundException here (use the received files as arguments)
}

Everything seems to be fine. Why is this happening and how to solve it ?

Sami
  • 165
  • 4
  • 19
  • 1. manual socket programming with RMI ??? 2. seems server code has hazards with files??? – Jacek Cz Jun 03 '18 at 13:50
  • 1
    1. i use socket with RMI to avoid overloading the server. 2. ? – Sami Jun 03 '18 at 13:56
  • "premature optimization is the root of all evil (or at least most of it) in programming" Donald Knuth – Jacek Cz Jun 03 '18 at 14:16
  • What on earth makes you think using both sockets and RMI changes the server load in any way? – user207421 Jun 03 '18 at 14:32
  • 2
    Because if you read the code i provided you will notice that after sending a file both socket and serverSocket are closed. – Sami Jun 03 '18 at 18:38
  • I *did* read the code you provided, and I *did* notice that, and it doesn't answer my question in any way, and neither does your comment. Creating extra sockets doesn't reduce anything. Try again, this time with an actual explanation. Not a mere statement. – user207421 Jun 03 '18 at 23:47
  • 2
    This actually will avoid the server from keep listening where there is no need. – Sami Jun 04 '18 at 01:13
  • 1
    No it doesn't. What you are doing creates an *extra* listening socket when there is no need. Your argument only makes sense if you think that RMI is completely free. Well, it isn't. How exactly do you think RMI works? It works by creating a listening socket. I would get rid of the RMI part altogether, and do the whole thing over a normal `ServerSocket` and `Socket`. It's not difficult. NB I can't imagine who is upvoting these meaningless comments of yours. – user207421 Jun 04 '18 at 07:38
  • 2
    If there is no easy way to do this with RMI [as you mentioned](https://stackoverflow.com/questions/50684395/java-file-transfer-over-rmi?noredirect=1#comment88429170_50684395), what can i do to improve my workaround ? – Sami Jun 05 '18 at 23:38
  • So your server is a client, and your client is a server, and one of them got a `FileNotFoundException`, and the other got an `EOFException`. Have you considered the possibility that these two events are related? – user207421 Jun 07 '18 at 10:48

1 Answers1

1

FileNotFoundException has two meanings:

  1. On input, the file wasn't found, couldn't be opened due to permissions, etc.
  2. On output, the target directory wasn't found, couldn't be written into due to permissions, etc.

For example if the filename you are sending contains a directory that doesn't exist at the server, you will get FileNotFoundException from new FileOutputStream.

There isn't enough (i.e. any) information in your question to say any more about that.

However:

  • You don't need object streams for this, or even data input/output streams. You're only using the basic read() and write() methods, so you may as well just use the socket streams directly.

  • You should use a larger buffer than 1024 bytes, say 8192 or a multiple thereof.

  • You can send multiple files per connection via the technique given in my answer to this question.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • @Sami No, I don't think I *could* be more clear. I expressed myself clearly. What part of 'you don't need object streams' or 'use the socket streams directly' don't you understand? You can't keep wasting other people's time asking them questions they've already answered, and you've already done it several times in this thread alone, for example the one above about the extra socket. – user207421 Jun 06 '18 at 01:50
  • @Sami No I wouldn't. It is clear that nothing I could possibly say would ever suffice. Now you're claiming not to understand the difference between object streams and the socket's streams. This sort of thing would clearly go on forever.. – user207421 Feb 15 '19 at 23:41