2017-02-17 102 views
2

服務器:發送對象,插座關閉

public Server() throws IOException { 
    socket = new ServerSocket(PORT); 
    while (true) { 
     Socket client = socket.accept(); 
     Spooker.get().getWindow().append(client.getInetAddress().getHostAddress() + " has connected."); 
     if (inetAddrFound(client.getInetAddress().getHostName())) { 
      System.out.println("Address found."); 
      Thread thread = new Thread(new SpookerClient(client)); 
      threads.put(client, thread); 
      thread.start(); 
     } 

    } 

} 

private class SpookerClient implements Runnable { 

    Socket sock; 
    ObjectInputStream ois; 
    ObjectOutputStream oos; 

    public SpookerClient(Socket socket) { 
     System.out.println("Creating Spooker client."); 
     this.sock = socket; 
     try { 
      this.oos = new ObjectOutputStream(socket.getOutputStream()); 
      oos.flush(); 
      this.ois = new ObjectInputStream(socket.getInputStream()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void run() { 
     Client client; 
     try { 
      Spooker.get().getWindow().append("Finding object."); 
      System.out.println("Finding object."); 
      while ((client = (Client) ois.readObject()) != null && !Thread.currentThread().isInterrupted()) { 
       System.out.println("Object found."); 
       Spooker.get().getWindow().append("Object found."); 
       if (keyFound(client.getKEY()) && idFound(client.getID())) { 
        Spooker.get().getWindow().append("Writing object."); 
        System.out.println("Writing object."); 
        oos = new ObjectOutputStream(sock.getOutputStream()); 
        oos.writeObject(Spooker.get().getConfiguration()); 
        oos.flush(); 
        threads.remove(sock); 
        Thread.currentThread().interrupt(); 
       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

客戶端:

public ClientConnection() { 
    try { 
     socket = new Socket(decode(ADDR), Integer.parseInt(decode(PORT))); 
     oos = new ObjectOutputStream(socket.getOutputStream()); 
     ois = new ObjectInputStream(socket.getInputStream()); 
     oos.writeObject(new Client()); 
     oos.flush(); 
     oos.close(); 
     Thread thread = new Thread(new IncomingSpookerConfiguration()); 
     thread.start(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

private class IncomingSpookerConfiguration implements Runnable { 

    SpookerConfiguration configuration; 

    @Override 
    public void run() { 
     System.out.println("Trying.."); 
     try { 
      while ((configuration = (SpookerConfiguration) ois.readObject()) != null && !Thread.currentThread().isInterrupted() && Spooker.get().getConfiguration() == null) { 
       System.out.println("Configuration loaded."); 
       Spooker.get().setConfiguration((SpookerConfiguration) ois.readObject()); 
       Thread.currentThread().interrupt(); 
       System.out.println(Spooker.get().getConfiguration().getX()); 
       socket.close(); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

我得到的錯誤是關閉套接字。我不明白爲什麼。

我想要做的是這個;

客戶端向服務器發送一個包含唯一標識符(CPUID,也爲found here)的客戶端類。服務器檢查客戶是否註冊 - 例如如果他們的cpuid在數據庫上。

如果cpuid位於數據庫中,服務器會發回一個「SpookerConfiguration」類,它基本上將是一個包含客戶端用來創建GUI的值的類(例如大小,標題,默認關閉操作等)。

我在做什麼錯?

編輯:

Client error: 

Trying.. 
java.net.SocketException: socket closed 
at java.net.SocketInputStream.socketRead0(Native Method) 
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) 
at java.net.SocketInputStream.read(SocketInputStream.java:171) 
at java.net.SocketInputStream.read(SocketInputStream.java:141) 
at java.net.SocketInputStream.read(SocketInputStream.java:224) 
at java.io.ObjectInputStream$PeekInputStream.peek 
(ObjectInputStream.java:2584) 
at java.io.ObjectInputStream$BlockDataInputStream.peek 
(ObjectInputStream.java:2891) 
at java.io.ObjectInputStream$BlockDataInputStream.peekByte 
(ObjectInputStream.java:2901) 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1502) 
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422) 
at com.spooker.connection.ClientConnection$IncomingSpookerConfiguration.run 
(ClientConnection.java:50) 
at java.lang.Thread.run(Thread.java:745) 

服務器錯誤:

java.net.SocketException: 
Software caused connection abort: socket write error 
at java.net.SocketOutputStream.socketWrite0(Native Method) 
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111) 
at java.net.SocketOutputStream.write(SocketOutputStream.java:155) 
at java.io.ObjectOutputStream$BlockDataOutputStream.drain 
(ObjectOutputStream.java:1877) 
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode 
(ObjectOutputStream.java:1786) 
at java.io.ObjectOutputStream.writeFatalException 
(ObjectOutputStream.java:1580) 
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:351) 
at com.spooker.server.Server$SpookerClient.run(Server.java:65) 
at java.lang.Thread.run(Thread.java:745) 
+0

請編輯您的文章,並在兩側包含完整的堆棧跟蹤。 –

+0

很多東西;它首先是因爲你寫的相當複雜,難以閱讀代碼。它從以下事情開始:爲什麼要創建**新的**對象流;儘管你已經在類的ctor中創建了一些?你爲什麼要將UI工作與這些代碼混合?事情是:你努力編寫能夠隱藏它真正做的事情的代碼。如果你現在正在尋找其他人來了解你的代碼在做什麼,這真的不會讓你感到驚訝...... – GhostCat

+0

@GhostCat我在混合UI工作,這樣人們很難破解我的軟件 - 所以如果他們「移除」認證過程(連接到服務器),軟件將不具有GUI值(字符串,整數,布爾等)來創建它自己。只是一個安全措施。 – Archie

回答

1
  1. socket closed意味着關閉套接字,然後繼續使用它。解決方案:不要。

  2. readObject()在流結束時不返回空值。它拋出EOFException。您的閱讀循環不正確。

  3. 您必須在套接字的生命週期中使用相同的對象流。