2017-02-17 65 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. 您必须在套接字的生命周期中使用相同的对象流。