2013-02-28 20 views
0

我想做一个套接字程序从两台PC同步文件在一起。所以基本上,我想先做一个单向同步。那么会发生什么呢..错误与多个ObjectOutputStream&ObjectInputStream(套接字关闭)

  1. 服务器和客户端通过套接字连接在一起。 (ok)
  2. 服务器通过objectoutputstream发送他拥有的文件列表,客户端通过objectinputstream接收它。 (ok)
  3. 客户端比较文件列表并通过objectoutputstream向服务器发回他没有的文件。 (ok)
  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(); 
     } 
    } 
} 

}

回答

2

java.net.SocketException异常:关闭套接字

那个异常意味着关闭了socket然后一直试图使用它。

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

+0

所以这意味着一旦我关闭输入/输出流,我该如何打开它? – Ferrino 2013-02-28 11:45:34

+1

OMG它的工作原理!感谢您的提示。在与另一个类似的线程(http://stackoverflow.com/questions/13727959/keeping-a-java-socket-open)检查后,我只是创建输入/输出流,永远不会关闭它。 – Ferrino 2013-02-28 12:04:11