一台服务器多个客户端

时间:2011-02-01 15:51:19

标签: java multithreading tcp

我遇到了以下问题:

  1. 我需要编写一个服务器程序,将接受多个客户端
  2. 所有客户都从服务器订阅相同的数据,例如股票价格更新。
  3. 每个客户端都可以向服务器发送简单的命令,如“logon”,“stop”
  4. 所以这是我的解决方案,因为我在多线程/ tcp中没有经验,我想知道这是一个很好的解决方案吗?如果没有,有没有更好的解决方案?是否有必要为每个客户端套接字都有一个线程?谢谢 顺便说一句:抱歉让每个人感到困惑,这是一个只涉及5-10个班级的小项目。

    class AcceptThread {
        ......
        public void run () {
            ControlThread controlThread = new ControlThread();
            controlThread.start();
    
            Socket socket = new Socket(port);
            while (!stop) {
                Socket s = socket.accept();
                controlThread.addClient (s);
            }
        }
    }
    
    class ControlThread {
        Set<Scoket> clients;
        SendDataThread sendDataThread;  
    
        public ControlThread () {
            sendDataThread = new SendDataThread();
            sendDataThread.start();     
        }
    
        public void addClient (Socket socket) {
            clients.add(socket);
            sendDataThread.addListener(socket);
        }
    
        public void run () {
            ......
            for (Socket s : clients) {
                if (s.getInputStream().available()) {
                    //read command from s
                }
            }
            ......              
        }
    }
    
    class SendDataThread () {
        Set<Scoket> listeners;
    
        public void addListener (Socket s) {
            listeners.add(s);
        }
    
        public void run () {
            for (Socket s: listeners) {
                // send data to each listener
            }
        }
    }
    

4 个答案:

答案 0 :(得分:3)

  

是否需要为每个客户端套接字创建一个线程?

不,事实上,我甚至不推荐它。如果这是一个小项目,而您不想使用任何现有的库,我建议您使用java.nio packageSelectableChannels。使用所谓的选择器,您可以轻松地以非阻塞方式监视客户端的传入数据。

以下是一些有用的链接:

答案 1 :(得分:0)

使用标准技术解决这个问题怎么样?

  

JMS主题       用于发布传递的消息的分发机制   对多个订阅者。

Tutorial

答案 2 :(得分:0)

  

谢谢顺便说一句:抱歉让每个人感到困惑,这是一个只涉及5-10个课程的小项目。

这绝对没有错。所有更高级别的抽象都是基于套接字的方式。除非您的项目足够大,否则无需拉出一系列其他框架/工具包来执行相同的工作。线程很便宜(甚至可以从多核架构中受益),尽管使用SelectableChannels作为@aioobe建议也不是一个坏主意。

当您的项目需要它时,您可以随时了解其他进程间通信方法(消息传递,远程方法调用等,以及它的大约100个实现)。

但是,您可能希望限制服务器同时使用的线程数。这可以通过声称例如大小等于您想要服务的线程数的信号量来容易地实现。另一个有趣的事情是使用java thread pools来更好地重用您的资源。

答案 3 :(得分:-1)

其他人提到过你可以使用nio库来减少必要的线程数。我只是想指出你当前的示例代码不起作用。在使用标准io流时,必须每个套接字使用一个线程。 available()方法几乎没用(通常)并且不会阻止你的控制线程阻塞。