2012-04-07 129 views
0

我开发了一个java swing客户端 - 服务器应用程序。服务器有许多服务,如数据库服务,缓存服务和客户服务对客户的谈话。在Socket中处理多个客户端

客户服务打开一个端口上的插座并监听传入的连接。它为每个客户端连接生成一个新线程,创建一个会话并读取传入的序列化对象。它维护这个会话(使线程保持活动状态)直到客户端发出'CLOSE_SESSION'命令。

什么,我想知道的是,如果它的正确产卵为每一个新的客户端插槽会话一个新的线程。谢谢。

我的客户服务代码如下所示。

代码来创建服务器套接字:

  try { 
       ServerSocket socket = new ServerSocket(serverPort); 
       Socket listener = socket.accept(); 

       Thread client = new Thread(new ClientHandler(listener)); 
       client.start(); 

      } catch (IOException ex) { 
       log.error(new Throwable(ex)); 
      } 

代码生成新线程为每个客户

class ClientHandler implements Runnable { 

private static Logger log = Logger.getLogger(ClientHandler.class); 

private Socket listener; 

public ClientHandler(Socket listener) { 
    this.listener = listener; 
} 

public void run() { 
    try { 
     ObjectInputStream inStream = new ObjectInputStream(
       listener.getInputStream()); 
     try { 
      ServiceRequestResponse request = (ServiceRequestResponse) inStream 
        .readObject(); 
      if (request != null && request.getServiceCommand() != null) { 

       ServiceCommand command = request.getServiceCommand(); 
       log.debug("command : " + command.getCommand()); 
       log.debug("is session alive? " + request.isAlive()); 
       log.debug("ServiceCommand.CREATE_SESSION : " 
         + ServiceCommand.CREATE_SESSION.getCommand()); 
       if (!request.isAlive() 
         && command.getCommand().equals(
           ServiceCommand.CREATE_SESSION.getCommand())) { 
        // No session yet, and service command issued is login. 
        // Call login service, check credentials and create 
        // session. 
        request.setSessionId(UUID.randomUUID()); 
        log.debug("Created user session with id : " 
          + request.getSessionId()); 
       } else { 
        if (command.getCommand().equals(
          ServiceCommand.CLOSE_SESSION)) { 
         // Close session and do clean up here 
        } 
        // Here session is alive. 
        while (!ServiceCommand.CLOSE_SESSION.equals(command 
          .getCommand())) { 
         // Read the service command from the request 
         // response and 
         // Hand it over to the appropriate handler. 
        } 

       } 

      } 

     } catch (ClassNotFoundException ex) { 
      log.error(new Throwable(ex)); 
     } 

    } catch (IOException ex) { 

    } 

} 

}

+0

您还应该(一)在该循环的底部捕捉EOFException类; (b)记录您在那里捕获的任何其他IOException;和(c)在finally {}块中关闭套接字。 – EJP 2012-04-07 06:29:49

回答

3

如果您的客户端会话请求能持续多久则线程per-连接是一个好的解决方案。

替代品有:

  • 使用NIO;
  • 如果客户端请求很短,则使用线程池。
+0

线程池听起来像个好主意,但是如何在这种情况下维护sessionid?由于它是一个池,每个线程都有一个关联的sessionid,它将被重用。我想保持sessionid唯一。 – sachinrahulsourav 2012-04-07 05:58:56

+0

可以将会话上下文关联到客户端套接字,例如,将客户端的套接字作为关键字的映射。或者,如果请求不频繁,您可以每次关闭套接字。这取决于你的要求。 – dash1e 2012-04-07 06:01:44