2015-01-31 59 views
0

所以我有一个带套接字连接的Client类。当客户端连接到服务器时,我首先读取该套接字以获取有关客户端的信息。然后,我将客户端移动到一个拥有所有连接客户端(发送其信息的客户端)的表格。然后,我听新连接的主要套接字是我创建客户端的地方。问题是我不确定何时以及是否有一个在套接字上读取的对象被销毁。我目前的策略是在第二张桌子上放置所有尚未发送信息的客户端(如果您愿意的话,可以使用未连接的客户端)。一旦客户发送他的信息,我将他从未连接的表格移动到连接的表格。我真的很讨厌这种方法。我只想在accept回调中创建客户端而不将其添加到表中。一旦接收到信息,客户端就会将其移动到连接的表格中。用套接字连接破坏Java对象

我目前的执行情况:

myMainChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>() 
     { 
       public void completed(final AsynchronousSocketChannel ch, void att) 
       { 
        // accept the next connection 
        myMainChannel.accept(null, this); 
        //add client to unconnected table 
        allUnconnectedClients.put(ch, new Client(ch)); 
       } 
       public void failed(Throwable exc, Void att) 
       {      
        exc.printStackTrace(); 
       } 

     }); 

客户端的构造函数中是第一次读操作。

id喜欢做的事情就是简单地创建客户端而不将它添加到表中。因此,换句话说repalce这样的:

allUnconnectedClients.put(ch, new Client(ch)); 

与此:

new Client(ch); 

我知道这有点怪异只创建一个局部变量不使用它,但有一个读超时(在构造函数中),将如果5秒内没有收到任何东西,请关闭所有设备

+0

糟糕的设计。不要在'accept()'循环中对客户进行I/O操作。 accept()循环除了接受连接之外不应该做任何事情,否则I/O可能会阻塞下一个客户端。重新设计这个。 – EJP 2015-01-31 23:30:08

+0

@EJP这是一个异步套接字,所以I/O工作实际上并没有阻塞任何东西,即使它不是在已完成的回调中以及在客户端上完成任何实际工作之前调用接受回调。如果需要在接受后立即完成I/O工作,我应该在哪里做? – Maro 2015-01-31 23:33:58

+0

下定决心。你说构造函数有一个超时读取。没有什么异步的。 – EJP 2015-02-01 00:00:32

回答

0

由于您可能会在任何给定时间等待读取或写入,因此您可以在任何给定时间使用接受附件+完成处理程序的read/write methods。你的Client将是附件。 处理程序将负责注册下一个读取或写入回调。如果没有,那么客户端将有资格进行垃圾回收。

认为它是继续传球。

+0

所以如果我通过客户端作为附件,那么它不会被垃圾收集直到有一个失败或完成? – Maro 2015-02-01 00:11:06