【问题标题】:Java chat Server with Thread Pool带有线程池的 Java 聊天服务器
【发布时间】:2013-09-16 03:53:06
【问题描述】:

我正在尝试使用线程池开发 Java 聊天服务器,但我不知道如何处理来自客户端的传入消息。我考虑将每个套接字连接保存在哈希图中并将任务添加到线程池队列中。但是服务器如何知道他何时从客户端接收消息而不实例化缓冲读取器?

【问题讨论】:

    标签: java chat threadpool


    【解决方案1】:

    您不需要为每个套接字初始化一个缓冲读取器。您可以查看一下是否有数据等待读取。

    for(Socket socket : socketsList)
        if(socket.getInputStream().available() > 0) {
            // you have data to be read from this socket
        }
    

    【讨论】:

    • 酷。但是一个不断迭代套接字列表的线程对于 cpu 来说是一个非常昂贵的操作,不是吗?
    • 我不会这么说,你可以将它与其他一些基本逻辑结合起来,比如 ping 出消息。因此,当您从该套接字接收到消息时,您还必须将其发送回给其他人。您可以将此逻辑与其他逻辑结合起来创建一个发送/接收线程。
    • 我不知道但是“可用”方法总是返回 0
    • 对不起,我没有检查套接字输入流是否会实现 .available() 看看这个帖子的答案stackoverflow.com/questions/5826198/…
    • 用“PushbackInputStream”类中的“可用”方法解决
    【解决方案2】:

    您的服务器将需要使用代理对象,这些代理对象包含从其套接字读取的 BufferedReader。也许您需要创建这些代理对象的集合。

    例如,

    class ServerAgent implements Runnable {
       private OutputStream out;
       private BufferedReader br;
    
       public ServerAgent(Socket clientSocket) throws IOException {
          out = clientSocket.getOutputStream();
          br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    
          // ....
       }
    
    
       @Override
       public void run() {
          // TODO finish code that reads from br, BufferedReader
    
       }
    }
    

    您的服务器可能有如下代码:

    while (true) {
       Socket clientSocket = server.accept();
       futureList.add(threadPoolExector.submit(new ServerAgent(clientSocket)));
    }
    

    【讨论】:

    • 抱歉,我不知道代理对象是什么。我有谷歌它,但我什么也没找到。你能给我一份指南吗?
    • 所以,如果我理解的话,我不应该使用“套接字列表”,但是当客户端想要向另一个客户端发送消息时,服务器会重新创建套接字连接,对吗?跨度>
    • @Daniele:考虑一下。套接字列表有什么好处?不多。
    • 好的,但是通过这种实现,服务器应该多次接受单个客户端,我的问题是:接受客户端非常昂贵(对于 cpu 和内存)?
    • @Daniele:要找到它的费用,您需要对事物进行概要分析。不过,我认为客户的“成本”不会成为您的问题。更重要的是有一个有效的程序。
    猜你喜欢
    • 2014-01-22
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    • 2015-09-25
    相关资源
    最近更新 更多