Hello all,
I'm trying to make my own dropbox kind of program. Just for the funs of it, and extreme customisation.
Now i've got a small problem while trying to send the file info in advance. Mostly the first time i connect everything goes just fine.
But as soon as another client connects it crashes, so i guess it's something with my server that is wrong. i get the following error:
I've been googling around this error, but find it quite hard to find a solution or anything for my problem. The only solution there seems to be is closing the sockets after usage. But this i already do. I found out that this error occurs when i try to write something to a closed socket.java.io.EOFException at java.io.DataInputStream.readInt(Unknown Source) at FileInfo.read(FileInfo.java:38) at FileSendRecieve.recieveFile(FileSendRecieve.java:30) at Client.run(Client.java:24) at java.lang.Thread.run(Unknown Source)
This class is used to store the information and then send it to the target
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.IOException; public class FileInfo { private String name; private String dir; private long size; private String checkSum = null; public FileInfo() { } public FileInfo(String name, String dir, long size) { this.name = name; this.dir = dir; this.size = size; } public FileInfo(File file) { this.name = file.getName(); this.dir = file.getPath(); this.size = file.length(); } public void setChecksum(String checkSum) { this.checkSum = checkSum; } /* * Protocol: first int: Amount of data is going to be send second int: type * of data third variable: data */ public void read(DataInputStream dis) throws IOException { int dataAmount = 0; dataAmount = dis.readInt(); for (int i = 0; i < dataAmount; i++) { int choice = 0; choice = dis.readInt(); switch (choice) { case 0: // do nothing break; case 1: name = readString(dis); break; case 2: dir = readString(dis); break; case 3: size = dis.readLong(); break; } } } /* * test * another test */ public void write(DataOutputStream dos) throws IOException { int dataAmount = 3; if (checkSum != null) dataAmount++; dos.writeInt(dataAmount); dos.writeInt(1); writeString(dos, name); dos.writeInt(2); writeString(dos, dir); dos.writeInt(3); dos.writeLong(size); dos.flush(); } public String getName() { return name; } public String getDir() { return dir; } public long getSize() { return size; } public boolean check(String checkSum) { if (this.checkSum.equals(checkSum)) return true; return false; } /** * Read string. * * @param dis * the dis * @return the string * @throws IOException * Signals that an I/O exception has occurred. */ protected String readString(DataInputStream dis) throws IOException { int length = dis.readInt(); StringBuilder sb = new StringBuilder(length); for (int i = 0; i < length; i++) { sb.append(dis.readChar()); } return sb.toString(); } /** * Write string. * * @param dos * the dos * @param string * the string * @throws IOException * Signals that an I/O exception has occurred. */ protected void writeString(DataOutputStream dos, String string) throws IOException { int length = string.length(); char[] data = string.toCharArray(); dos.writeInt(length); for (int i = 0; i < length; i++) { dos.writeChar(data[i]); } } public void print() { System.out.println("Name:" + name + " Size:" + size + " dir:" + dir); } }
A commonly class to send and recieve file info:
public class FileSendRecieve { Socket socket; OutputStream socketOut; InputStream socketIn; public FileSendRecieve(Socket socket) { try { socketOut = socket.getOutputStream(); socketIn = socket.getInputStream(); } catch (IOException e) { e.printStackTrace(); } this.socket = socket; } public void sendFile(String name, String directory) throws IOException { File file = new File(name); FileInfo fileinf = new FileInfo(file); fileinf.write(SocketUtil.wrapOutputStream(socket)); } public void recieveFile() throws IOException { FileInfo fileinf = new FileInfo(); fileinf.read(SocketUtil.wrapInputStream(socket)); fileinf.print(); } public void stop() { SocketUtil.close(socketIn); SocketUtil.close(socketOut); SocketUtil.close(socket); } }
My server:
public class Server extends Thread { private boolean run = false; private float runTime; private ServerSocket ss = null; private Socket cs = null; public Server() { runTime = System.nanoTime(); } public void startService() { try { ss = new ServerSocket(8081); run = true; } catch (IOException e) { System.exit(0); } this.start(); } public void run() { while (run) { try { cs = ss.accept(); new Thread(new ClientHandler(cs)).start(); } catch (Exception e) { System.exit(1); } } } class ClientHandler implements Runnable { FileSendRecieve fsr; public ClientHandler(Socket cs) { fsr = new FileSendRecieve(cs); } public void run() { try { fsr.sendFile("image.png", "c:\\"); fsr.sendFile("image2.png", "c:\\"); fsr.stop(); } catch (IOException e) { e.printStackTrace(); } } } public static void main(String args[]) { Server server = new Server(); server.startService(); } }
and my client
import java.io.IOException; import java.net.Socket; public class Client implements Runnable { FileSendRecieve fsr; public Client(Socket socket) { fsr = new FileSendRecieve(socket); } public static void main(String args[]) { Socket s = null; try { s = new Socket("127.0.0.1", 8081); } catch (Exception e) { System.exit(0); } new Thread(new Client(s)).start(); } @Override public void run() { try { fsr.recieveFile(); fsr.recieveFile(); fsr.stop(); } catch (IOException e) { e.printStackTrace(); } } }
Also here is my socketWrapper. i use it to wrap my sockets in. And i use the close functions.
/** * This class contains some useful socket and networking utilities. * * @author Elmar */ import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.Closeable; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.DatagramSocket; import java.net.ServerSocket; import java.net.Socket; public class SocketUtil { /** * This class wraps a output socket into a buffered data outputStream * * @param socket * The socked to wrap * @return Returns the Buffered dataOutputStream * @throws IOException * Should get handled in the function itself */ public static DataOutputStream wrapOutputStream(Socket socket) throws IOException { return new DataOutputStream(new BufferedOutputStream( socket.getOutputStream())); } /** * This class wraps a output socket into a buffered data inputStream * * @param socket * The socked to wrap * @return Buffered dataInputStream * @throws IOException * Should get handled in the function itself */ public static DataInputStream wrapInputStream(Socket socket) throws IOException { return new DataInputStream(new BufferedInputStream( socket.getInputStream())); } /** * Closes the given {@link Closeable}. * * @param closeable * the closeable */ public static void close(Closeable closeable) { try { if (closeable != null) { closeable.close(); } } catch (IOException exception) { } } /** * Closes the given {@link Socket}. * * @param socket * the socket */ public static void close(Socket socket) { try { if (socket != null) { socket.close(); } } catch (IOException exception) { } } /** * Closes the given {@link ServerSocket}. * * @param serverSocket * the server socket */ public static void close(ServerSocket serverSocket) { try { if (serverSocket != null) { serverSocket.close(); } } catch (IOException exception) { } } /** * Closes the given {@link DatagramSocket}. * * @param socket * the socket */ public static void close(DatagramSocket socket) { if (socket != null) { socket.close(); } } }