当前位置: 首页 > 知识库问答 >
问题:

基于某些参数获取对另一个线程的引用

爱博达
2023-03-14

我正在开发一个Java客户端/服务器聊天应用程序,允许局域网内的用户在他们之间聊天。

在服务器应用程序中,我有一个主类,每当客户端连接到服务器时,它都会创建一个不同的线程。所以,基本上,我会打开一个TCP连接,每个客户端都在一个单独的线程上运行。

我在发送消息时遇到问题。当用户向服务器发送新消息时,服务器必须找到与目标用户有连接的线程并将该消息发送给他。我该怎么做。我已经将每个线程与一个用户对象相关联,因此我需要执行类似findThreadByUser(user)的操作,并且在获得引用后,只需调用发送消息的方法。我该怎么做?

下面是实现Runnable的ConnectionHandler类的一部分。我想访问该类的特定实例,更具体地说,是它的末尾的方法< code > sendToClient(String message)(外部运行方法)。我尝试使用HashMap来存储用户和线程,但是我无法访问< code > sendToClient(String message)方法

public class ConnectionHandler implements Runnable {

protected Socket socket;
private ServerData serverData;
private User currentUser;
BufferedReader inFromClient;
PrintStream outToClient;
String clientSentence;
String peerIp;
String peerHostName;

public ConnectionHandler(Socket socketToHandle, ServerData serverData) {
    socket = socketToHandle;
    this.serverData = serverData;
    inFromClient = null;
    outToClient = null;
    currentUser = null;

    clientSentence = " ";
}

@Override
public void run() {
peerIp = socket.getInetAddress().getHostAddress();
    peerHostName = socket.getInetAddress().getHostName();
    try {
        outToClient = new PrintStream(socket.getOutputStream(), true);

        /* Create a reading stream to the socket */

        inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    } catch (IOException ex) {
        Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
        System.out.println("Error creating buffered handles.");
    }

    System.out.println("Handling connection to client at " + peerIp + " --");

    Runnable r1 = new Runnable() {

        public void run() {
            while (true) {
                try {
                    /* Read client's message through the socket's input buffer */
                    clientSentence = inFromClient.readLine();
                } catch (IOException e) {
                    System.out.println(socket.getInetAddress() + "-" + peerIp + " broke the connection.");
                    break;
                }
                /* Output to screen the message received by the client */
                System.out.println("Message Received: " + clientSentence);

                List<String> processedClientSentence = ClientMessageProcessor.process(clientSentence);

                if (processedClientSentence.get(0).equals(new String("LOGIN"))) {
                    String result = ServerActions.login(peerIp, peerHostName, processedClientSentence.get(1), serverData);

                    if (result.equals("success")) {
                        currentUser = serverData.getUserByIP(peerIp);
                        outToClient.println("USERS \"" + ServerActions.getUsers(serverData) + "\"");
                    } else {
                        outToClient.println("ERROR \'" + result + "\'");
                    }
                } else if (processedClientSentence.get(0).equals(new String("GETUSERS"))) {
                    outToClient.println("USERS \"" + ServerActions.getUsers(serverData) + "\"");
                } else if (processedClientSentence.get(0).equals(new String("USERINFO"))) {
                } else if (processedClientSentence.get(0).equals(new String("MESSAGE"))) {
                    ServerActions.sendMessage(currentUser/*.getUserName()*/, processedClientSentence.get(1), processedClientSentence.get(2), serverData);
                } else if (processedClientSentence.get(0).equals(new String("LOGOUT"))) {
                } else {
                }

            }
        }
    };
    new Thread(r1).start();
}

public void sendToClient(String message) {
    outToClient.println(message);
}

}

共有2个答案

高山
2023-03-14

为什么不发送广播,让正确的客户端接受消息呢?

鲁永福
2023-03-14

将客户端对象存储HashMap 中,用户名(这将是唯一的)作为键,与之关联的线程作为值......”

 类似资料:
  • 问题内容: 如何编写一个在ES6中仅以最紧凑的方式仅包含很少的属性的函数? 我想出了使用解构+简化对象文字的解决方案,但是我不喜欢代码中重复的字段列表。 有没有更苗条的解决方案? 问题答案: 尽管不能避免重复字段列表,但这里有些苗条。它使用“参数解构”来避免需要该参数。 @EthanBrown的解决方案更为通用。这是它的更惯用的版本,它使用和计算的属性(部分): 如果我们要保留属性的属性(例如和和

  • 问题内容: 如果知道与该线程关联的ID,该如何获取正在运行的线程的引用? 例如 问题答案: 您有2种方法可以做到。两者都很简单: 旧方法:获取您可以循环访问..getParent()的根线程组。并打电话 较新(但速度较慢)。 第一种方法有一个小问题,由于存在错误,ThreadGroup可能根本无法枚举任何东西。 第二个比较慢,但是有安全漏洞。

  • 问题内容: 我一直都在看:声明的对象常量使某些键用引号引起来,而另一些则没有。jQuery 1.4.2中的示例: **用引号 将前两个属性键(和 ) 包裹 起来,而其他两个都不用引号引起来的意义是什么? 有什么区别吗? 我一直在摸索ECMAScript 5规范;我所能找到的只是[ 15.12.3节的注6,重点是我的 ]: 注6:一个对象呈现为左括号,后跟零个或多个属性,以逗号分隔,右括号封闭。 属

  • 我必须得到如下输出: 这是我的密码。没有错误。它以PlusThread开始并打印第一行。然后它将释放锁。之后,MultiplyThread开始运行。它将打印所有行,而不是通知PlusThread。 这是我的输出:

  • 我想将输入XML转换为输出XML。同样,使用xslt进行XML转换。 输入xml和支持xml文件位于本地路径中(仅限同一路径)。 XSl和saxon9。jar位于服务器路径中。 将在本地路径中创建输出xml(与输入xml路径相同)。 使用xslt2.0我可以得到一个输入的xml值,但不能得到支持的xml值(存在于本地) d:\测试 下面是我的xsl用于从supporting.xml获取值 有人能帮

  • 问题内容: 考虑: 我该怎么做: 显然,这不起作用,因为第一个索引名为,而不是。 可以,但是我不知道它的名字叫foo。它可以命名为任何东西。我只想要第一个。 问题答案: 如果对象的顺序很重要,则应修改JSON模式以将对象存储在数组中: 或许: 正如Ben Alpert指出的那样,Javascript对象的属性是无序的,并且如果希望它们按与对象常量中指定的顺序相同的顺序枚举,则代码将被破坏-没有“f