0
votes

I am trying to make a socket program to sync files from two PC together. So basically, I am trying to make a one way sync first. So what happens is..

  1. Server and Client connect together through socket. (ok)
  2. Server sends the list of files he has through ObjectOutputStream and Client receives it through ObjectInputStream. (ok)
  3. Client compare the list of files and sends to server back (through ObjectOutputStream) the files he does not have. (ok)
  4. Server sends the missing files to client. (problem here)

My error is on the server side it shows:

java.net.SocketException: Socket is closed
at java.net.Socket.getOutputStream(Unknown Source)
at ee4210.TcpServer$ConnectionRequestHandler.run(TcpServer.java:116)
at ee4210.TcpServer.handleClientRequest(TcpServer.java:80)
at ee4210.TcpServer.startServer(TcpServer.java:72)
at ee4210.TcpServer.main(TcpServer.java:39)

I believe it has something to do about ObjectOutputStream and ObjectInputStream because if I don't close the ObjectOutputStream or ObjectInputStream, it can work.

Can the client have both ObjectOutputStream and ObjectInputStream to send/receive objects? Similarly, can the server have both too?

Appreciate your help. Sorry for the long post. I like to be as detailed as possible.

My Client Code:

package ee4210;

import java.io.* ;
import java.net.* ;
import java.util.* ;public class TcpClient{
static ObjectOutputStream out;
static ObjectInputStream in;
String message;
int portNo=2004;
static Socket _socket = null;   
InetAddress host = null;
static LinkedList destinationfiles = new <String>LinkedList();
static LinkedList sourcefiles = new <String>LinkedList();
static LinkedList missingfiles = new <String>LinkedList();
String filename=null;

TcpClient(){}

public static void listFilesForFolder(final File folder) { //no need to read this
    for (final File fileEntry : folder.listFiles()) {
        if (fileEntry.isDirectory()) {
            listFilesForFolder(fileEntry);
        } else {
            //System.out.println(fileEntry.getName());
            destinationfiles.add(fileEntry.getName());
        }
    }
}

public static void getListfromPeer() {
    try {
        in=new ObjectInputStream(_socket.getInputStream());
        sourcefiles = (LinkedList) in.readObject();
        //in.close(); //if i close, got error
    } catch (ClassNotFoundException | IOException classNot) {
        System.err.println("data received in unknown format");
    }

}

public static void compareList() {
    // go through each of the peer's filename, check against urs. If dont
    // have, download
    ListIterator iter = sourcefiles.listIterator();
    String filename;
    while (iter.hasNext()) {
        // System.out.println(iter.next());
        filename=(String) iter.next();
        if (!destinationfiles.contains(filename)) //file cannot be found
        {
            missingfiles.add(filename);
        }
    }

}

public static void main(String[] args) {
    /*Check if directory exist, create one if doesnt exit*/
    File theDir = new File("src/ee4210/files");

    // if the directory does not exist, create it
    if (!theDir.exists()) {
        System.out.println("creating directory..");
        boolean result = theDir.mkdir();
        if (result) {
            System.out.println("Successfully created directory");
        }

    }
    /*Get the list of files in that directory and store the names in array*/
    listFilesForFolder(theDir);

    /*Connect to peer*/
    try {
        new TcpClient().connect();
        //new TcpClient().checkForInput();

    } catch (Exception e) {
        System.out.println("Something falied: " + e.getMessage());
        e.printStackTrace();
    }

}

public void connect() throws IOException 
{

    try {
        host = InetAddress.getLocalHost();
        //_socket = new Socket(host.getHostName(), portNo);
        _socket = new Socket("172.28.177.125", portNo);
        //System.out.println(host.getHostAddress()); //get the IP address of client

        /*Get list from peer and compare list*/
        getListfromPeer(); //receive from Server
        compareList();
        System.out.println(missingfiles);

        /*Send to server the list of missing files*/

        do
        {
            //busy wait till socket is open
        }while (_socket.isClosed());
        out = new ObjectOutputStream(_socket.getOutputStream());
        out.flush();
        out.writeObject(missingfiles);
        out.flush();
        System.out.println("Client have finished sending missing linkedList over");
        out.close();

    } catch (Exception e) {
        e.printStackTrace();
    } 
}

}

Server Code:

 package ee4210;

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

public class TcpServer extends Thread
{
ServerSocket providerSocket;
Socket connection = null;
static ObjectOutputStream out;
ObjectInputStream in;
String message;
int portNo=2004; //portNo is 2004
TcpClient tcpclientobject = new TcpClient();
static LinkedList destinationfiles = new <String>LinkedList();
static LinkedList missingfiles = new <String>LinkedList();

public static void main(String[] args) 
{
    /*Check if directory exist, create one if doesnt exit*/
    File theDir = new File("src/ee4210/files");

    // if the directory does not exist, create it
    if (!theDir.exists()) {
        System.out.println("creating directory..");
        boolean result = theDir.mkdir();
        if (result) {
            System.out.println("Successfully created directory");
        }

    }
    /*Get the list of files in that directory and store the names in array*/
    listFilesForFolder(theDir);

    /*Connect*/
    try {
        new TcpServer().startServer();
    } catch (Exception e) {
        System.out.println("I/O failure: " + e.getMessage());
        e.printStackTrace();
    }

    /*Rest of the code in run()*/


}

public static void listFilesForFolder(final File folder) {
    for (final File fileEntry : folder.listFiles()) {
        if (fileEntry.isDirectory()) {
            listFilesForFolder(fileEntry);
        } else {
            //System.out.println(fileEntry.getName());
            destinationfiles.add(fileEntry.getName());
        }
    }
}
public void startServer() throws Exception {
    ServerSocket serverSocket = null;
    boolean listening = true;

    try {
        serverSocket = new ServerSocket(portNo);
    } catch (IOException e) {
        System.err.println("Could not listen on port: " + portNo);
        System.exit(-1);
    }

    while (listening) {
        handleClientRequest(serverSocket);
    }

    serverSocket.close();
}

private void handleClientRequest(ServerSocket serverSocket) {
    try {
        new ConnectionRequestHandler(serverSocket.accept()).run();
    } catch (IOException e) {
        e.printStackTrace();
    }
}


public class ConnectionRequestHandler implements Runnable{
    private Socket _socket = null;

    public ConnectionRequestHandler(Socket socket) {
        _socket = socket;
    }
    public void run() {
        System.out.println("Client connected to socket: " + _socket.toString());

        /*Send the linkedlist over*/
        try {
            out = new ObjectOutputStream(_socket.getOutputStream());
            //out.flush();
            out.writeObject(destinationfiles);
            out.flush();
            //out.close(); //if I close, will have errors
        } catch (IOException e) {
            e.printStackTrace();
        }
        receiveMissingFileNames(); //this one is still ok

        try { //if i put the close here its ok
            out.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try { 
            out = new ObjectOutputStream(_socket.getOutputStream()); //when I add this line it shows the error
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public void receiveMissingFileNames()
    {
        try {

            in=new ObjectInputStream(_socket.getInputStream());
            System.out.println("Is the socket connected="+_socket.isConnected());
            missingfiles=(LinkedList) in.readObject();
            System.out.println(missingfiles);
            in.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

}

1

1 Answers

2
votes

java.net.SocketException: Socket is closed

That exception means that you closed the socket and then kept trying to use it.

Closing the input stream or output stream of a socket closes the other stream and the socket.