0

我正在尝试制作一个套接字程序来同步来自两台 PC 的文件。所以基本上,我试图先进行单向同步。所以发生的事情是..

  1. 服务器和客户端通过套接字连接在一起。(好的)
  2. 服务器通过 ObjectOutputStream 发送他拥有的文件列表,客户端通过 ObjectInputStream 接收它。(好的)
  3. 客户端比较文件列表并将他没有的文件发送回服务器(通过 ObjectOutputStream)。(好的)
  4. 服务器将丢失的文件发送给客户端。(这里有问题)

我的错误出现在服务器端,它显示:

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)

我相信它与 ObjectOutputStream 和 ObjectInputStream 有关,因为如果我不关闭 ObjectOutputStream 或 ObjectInputStream,它可以工作。

客户端可以同时拥有 ObjectOutputStream 和 ObjectInputStream 来发送/接收对象吗?同样,服务器也可以两者兼得吗?

感谢你的帮助。对不起,很长的帖子。我喜欢尽可能详细。

我的客户代码:

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();
    } 
}

}

服务器代码:

 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();
        }
    }
}

}

4

1 回答 1

2

java.net.SocketException:套接字已关闭

该异常意味着关闭了套接字,然后继续尝试使用它。

关闭套接字的输入流或输出流会关闭另一个流和套接字。

于 2013-02-28T08:32:26.380 回答