0

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

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

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

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

}

4

3 回答 3

2

将 Client 对象存储在 aHashMapUserName(将是唯一的)作为 Key,并将与其关联的线程作为 Value...`

于 2012-06-17T17:31:53.300 回答
1

您可以查看这些问题以寻求帮助..
1. Java 中的多线程聊天服务器
2. 使用套接字的多线程客户端-服务器聊天
3. ClientServerThreads。

于 2012-06-17T17:31:31.117 回答
-1

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

于 2012-06-17T17:44:34.230 回答