使用Java向特定客户端发送消息

5
我如何从服务器向特定客户端发送消息?我知道如何做,例如我必须列出所有连接到服务器的客户端,然后通过迭代每个客户端来发送消息,但如果有人能帮我编写代码,我将不胜感激。我已经查找了许多代码,但没有得到实质性的帮助。代码不应该基于GUI。提前致谢,对我的糟糕英语表示抱歉。
这是我向所有客户端发送消息的代码,但我想使用客户端的IP地址向选择的客户端发送消息。
Map<Integer, java.net.Socket> clients = new HashMap<Integer, java.net.Socket> ();
socket = serverSocket.accept();

// Add the socket to a HashMap
clients.put(socket.getPort(), socket);
for (Iterator<Integer> iter = clients.keySet().iterator(); iter.hasNext(); )
{
    int key = iter.next();

    java.net.Socket client = clients.get(key);

    // Sending the response back to the client.
    // Note: Ideally you want all these in a try/catch/finally block
    OutputStream os = client.getOutputStream();
    OutputStreamWriter osw = new OutputStreamWriter(os);
    BufferedWriter bw = new BufferedWriter(osw);
    bw.write("Some message");
    bw.flush();
}

我刚看到你把这个问题单独列出来了。这取决于你想要如何识别你想要单独处理的客户端。你知道你想怎样做吗? - Michael Markidis
是的,一旦客户端连接到服务器,它会将其IP地址和用户名发送到服务器,现在我想使用这些IP地址向任何特定的客户端发送消息。其中一个选项是,如果我想将消息发送给IP地址为192.168.1.1的客户端,则将消息和IP地址发送到所有客户端,然后在客户端上简单地应用检查,以确定哪个客户端具有该IP地址,如果其中任何一个客户端具有该IP地址,则将该消息显示给他。 - zeeshan nisar
5个回答

3
我会创建一个客户端类(Client class):
class Client
{
   private String userName;
   private String ipAddress;
   private java.net.Socket socket = null;

   public Client (String userName, String ipAddress, java.net.Socket socket)
   {
      this.userName = userName;
      this.ipAddress = ipAddress;
      this.socket = socket;
   }

   public java.net.Socket getSocket()
   {
       return this.socket;
   }
}

我建议将用户名和IP地址的组合映射到一个客户端对象,而不是仅将套接字和端口号添加到映射表中。

socket = serverSocket.accept();

// get the username from the socket
// get the ipAddress from the socket
Client c = new Client(userName, ipAddress, socket);

// Add the client to a HashMap
clients.put(userName + ":" + ipAddress, c);

现在,您可以根据用户名和IP地址向特定客户端发送消息:
public void sendToOneClient (String userName, String ipAddress, Map<String, Client> clients)
{
    Client c = clients.get(userName + ":" + ipAddress);

    java.net.Socket socket = c.getSocket();

    // Sending the response back to the client.
    // Note: Ideally you want all these in a try/catch/finally block
    OutputStream os = socket.getOutputStream();
    OutputStreamWriter osw = new OutputStreamWriter(os);
    BufferedWriter bw = new BufferedWriter(osw);
    bw.write("Some message");
    bw.flush();
}

2

我会使用Socket.getInetAddress(),并将结果与你要发送到的IP进行比较。个人建议使用String[]ArrayList<String>存储IP地址。以下是一个示例:

ArrayList<String> addresses;
//TODO: Add things to 'addresses'

clients.put(socket.getPort(), socket);
for (Iterator<Integer> iter = clients.keySet().iterator(); iter.hasNext(); )
{
    int key = iter.next();

    java.net.Socket client = clients.get(key);

    //Checking to make sure it's a client we want to send to.
    if (addresses.contains(client.getInetAddress().toString()) {
        // Sending the response back to the client.
        // Note: Ideally you want all these in a try/catch/finally block
        OutputStream os = client.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(os);
        BufferedWriter bw = new BufferedWriter(osw);
        bw.write("Some message");
        bw.flush();
    }
}

或者,您可以按照 InetAddress 的方式将套接字存储在 HashMap 中。


1
你可以存储客户端的套接字和它们所在的位置之间的关系。自然的方法是使用类似于映射的数据结构,如:
Map<String, Socket> sockets = new HashMap<String,Socket>();
...
ServerSocket ss = ...;
Socket s = ss.accept();
String username = getUserName(s);
sockets.put(username, s);

显然,在这个例子中,客户端必须以你期望接收到的格式发送他/她的用户名,此后进行Socket连接。

我认为应该是sockets.put(userID,s) @ControlAltDel - zeeshan nisar

0
我发现创建一个对象类型,可以同时保存唯一的名称或ID(无论是int还是String),以及Socket是有效的。您可以将此对象的实例存储在ArrayList(或任何其他列表)中,并通过迭代它们来搜索要使用的名称或ID。

0

这是我为我的程序所做的。在这里,我使用了">>"字符串来指定将消息发送给特定的用户。(例如:"Ross>>Hi Ross What's Up?" 表示该消息应发送给名为'Ross'的用户)。我使用了一个HashMap(命名为'WritersMap')来保存细节作为键值对。键将是发送特定消息的用户的名称,值将是该消息。'in' 是一个 BufferedReader 实例。

while (true) {
                    String input = in.readLine();
                    if (input == null) //if there is no input,do nothing
                    {
                        return;
                    }

                    //when a user sends a message to a specific user
                    else if(input.contains(">>"))   //checks whether the message contains a >> 
                    {
                        String person=input.substring(0,input.indexOf(">"));    //extract the name of the destination user 
                        for(HashMap.Entry<String,PrintWriter> entry:writersMap.entrySet())  //find the destination user from the users list 
                        {
                            if(entry.getKey().matches(person))  //if the destination user is found 
                            {
                                PrintWriter writer=entry.getValue();
                                writer.println("MESSAGE " + name + ": " + input);
                            }
                        }
                    }
                    else    //when a user sends a broadcast message to all users 
                    { 

                        for(HashMap.Entry<String,PrintWriter> entry:writersMap.entrySet())  //find the destination user from the users list 
                        {
                            PrintWriter writer=entry.getValue();
                            writer.println("MESSAGE " + name + ": " + input);
                        }
                    }
                }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接