如何分组到2个客户端以发送消息 [英] How to group to 2 clients to send messages

查看:62
本文介绍了如何分组到2个客户端以发送消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做的是第2组客户,并使他们彼此交流。因此,如果连接了2个客户端,则它们只能彼此通信;如果连接了第三个客户端,则它将无法与其他2个客户端通信,但它将创建另一个由2个客户端组成的组,依此类推...下面的代码当前将一个消息从一个客户端广播到所有客户端,但是我希望它像上面描述的那样工作,并且一直很难找到解决方案。

What i'm trying to do is group 2 clients and make them communicate with eachother. So if 2 clients are connected they would only be able to communicate with eachother and if a third client got connected it would not be able to communicate with the 2 other clients but it would create another group of 2 clients and so on... My code below currently broadcasts one message from one client to all clients but i would like it work like described above and have been having a difficult time finding a solution. Any help is appreciated.

public class ChatServer {


private static final int PORT = 9001;


private static HashSet<String> names = new HashSet<String>();


private static HashSet<PrintWriter> writers = new HashSet<PrintWriter>();

static int clientCounter = 0;


public static void main(String[] args) throws Exception {
    System.out.println("The chat server is running.");
    ServerSocket listener = new ServerSocket(PORT);
    try {
        while (true) {
            new Handler(listener.accept()).start();
        }
    } finally {
        listener.close();
    }
}


private static class Handler extends Thread {
    private String name;
    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;

    
    public Handler(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        try {

            
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream(), true);

            
            while (true) {
                out.println("SUBMITNAME");
                name = in.readLine();
                if (name == null) {
                    return;
                }
                synchronized (names) {
                    if (!names.contains(name)) {
                        names.add(name);
                        break;
                    }
                }
            }

            
            out.println("NAMEACCEPTED");
            
            clientCounter++;
            

            
                if (clientCounter > 0 && clientCounter <= 2) {

                    writers.add(out);

                    
                    while (true) {
                        String input = in.readLine();
                        if (input == null) {
                            return;
                        }

                        for (PrintWriter writer : writers) {
                            writer.println("MESSAGE " + name + ": " + input);
                        }

                    }

                } else {
                    clientCounter = 1;
                }
            
            

            
            
            
        } catch (IOException e) {
            System.out.println(e);
        } finally {
            
            if (name != null) {
                names.remove(name);
            }
            if (out != null) {
                writers.remove(out);
            }
            try {
                socket.close();
            } catch (IOException e) {
            }
        }
    }
}

}

推荐答案

这是使其工作的一种方法。首先,您需要修改接受连接的循环,以使其跟踪先前接受的套接字。当客户端连接时,您检查是否存在 previousSocket :如果没有,则将其当前套接字存储为 previousSocket 。如果有一个,则您现在有两个已连接的客户端,它们可以相互通信:

Here's one way to make it work. First you need to modify the loop that accepts connections, so that it keeps track of a "previously accepted socket". When a client connects, you check if there is previousSocket: if there isn't you store the current its socket as previousSocket. If there is one, you now have two clients that have connected, and they can communicate with each other:

Socket previousSocket = null;
while (true) {
    Socket newSocket = listener.accept();
    if (previousSocket == null) {
        previousSocket = newSocket;
    } else {
        new Handler(previousSocket, newSocket).start();
        new Handler(newSocket, previousSocket).start();
        previousSocket = null;
    }
}

您需要进行的另一项更改是添加对等到您的Handler类。对等体是用于与其他客户端进行通信的套接字。然后用将代码发送到所有客户端的 for 循环替换为仅将消息发送到对等方的代码:

The other change you will need is to add the concept of a "peer" to your Handler class. The peer is the socket that you use to communicate with the other client. Then you replace the for loop that sends messages to all clients with code that sends the message to the peer only:

peerOut.println("MESSAGE " + name + ": " + input);

下面是经过修改的Handler类的更完整的代码示例。为了简便起见,我省略了名称注册和错误处理-您需要将其重新添加。

Here's a more complete code sample for the modified Handler class to illustrate. I've omitted the name registration and error handling for brevity - you'll need to add it back.

private static class Handler extends Thread {
    private String name;
    private Socket socket;
    private Socket peerSocket;
    private BufferedReader in;
    private PrintWriter out;

    public Handler(Socket socket, Socket peerSocket) {
        this.socket = socket;
        this.peerSocket = peerSocket;
    }

    public void run() {
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        // name registration and error handling omitted for brevity

        PrintWriter peerOut = new PrintWriter(peerSocket.getOutputStream(), true);

        while (true) {
            String input = in.readLine();
            if (input == null) {
                return;
            }

            // Replaces "for (PrintWriter writer : writers) { ... }"
            peerOut.println("MESSAGE " + name + ": " + input);
        }
    }
}

这篇关于如何分组到2个客户端以发送消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆