套接字服务器 - 通过客户端消息

时间:2014-01-21 19:36:34

标签: java sockets

我正在创建一个聊天客户端。我有多个客户连接,但我很难让他们互相交谈。如何让服务器将客户端1传入的消息发送给其他客户端而不使用client1的回显?我还没有发现任何识别每个客户的方法。

public class connect1 extends Thread {
    public void run() {
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(4444); 
            while (acceptMore) {
                Socket send1socket = serverSocket.accept();
                new Thread(new sendRunnable(send1socket)).start();
            }
        } catch (IOException exp) {
            exp.printStackTrace();
        }
    }
} //this thread starts my Runnable where I have my PrintWriter

2 个答案:

答案 0 :(得分:0)

最简单的方法是使用一个数组或套接字列表,并在客户端离开时每次新客户端连接/减去时添加它。

然后,当收到消息时,循环遍历该数组/列表并向其他客户端发送消息。 (确保检查您所在的客户端对列表中的当前客户端,以便您不向发送给服务器的客户端发送消息)

虽然这种情况很小,但它会导致大规模问题,因为每次收到新邮件时都必须遍历一个大型列表。

要有chatRooms或其他东西,你可以拥有一个多维数组(Array[room][socket]) 然后你可以循环通过某些房间,只发送给那些客户,或循环所有,等等。

要仅向特定用户发送,您可以拥有一个User.java类,其中包含用户名和套接字。然后,不是做一个套接字数组,而是使用一组用户并在你的循环中检查用户名,只发送给所需的用户。

流速: UserA连接到服务器,发送用户名为bob 服务器接收连接,创建新的User对象,将用户名设置为bob并将套接字设置为用户套接字,然后将该用户对象添加到User[]

UserB连接到服务器,发送用户名john 同样的交易,服务器制作新的用户对象等等。

john向服务器发送一条消息,告诉它只将消息发送给bob 服务器循环通过User[]并检查它们的用户名,如果用户名与该用户对象上的bob服务器调用getSocket匹配,则返回该用户的套接字连接。 然后,服务器获取该套接字的outputStream,并使用它创建一个printwriter。它通过新创建的打印编写者发送从john收到的消息。

答案 1 :(得分:-1)

如果您的问题是如何通过套接字发送/接收消息,以下是一种方法。

发送:

String message = "..." // message to send
output = new DataOutputStream(socket.getOutputStream());
output.writeInt(message.getBytes().length);  // first you send how long the message is
output.write(message.getBytes(), 0, message.getBytes().length);  // then you send the message

并阅读:

DataInputStream input = new DataInputStream(socket.getInputStream());
if(input.available() > 0) {  // important - makes sure the code doesn't "block" and wait for input
    byte[] bytes = new byte[input.readInt()]; // makes a byte[] of the size of the message it's going to read
    input.read(bytes,0,bytes.length);  // reads the actual message to the byte array
    String message = new String(bytes,0,bytes.length,"UTF-8");  // convert the message back into a String
}

您应该看到Socket#getOutputStream()Socket#getInputStream(),然后使用DataInputStreamDataOutputStream类中的方法。 input.ava

至于您的其他问题,如果您希望客户端能够向特定的其他客户端发送消息,则客户端必须确切地知道要将消息发送到哪个客户端。当客户端向服务器发送消息时,该信息必须是消息的一部分。服务器将使用它有选择地将消息发送到特定的Sockets

当然必须有一个系统。例如,对于聊天应用,每个客户端可能都有一个用户名。您可以拥有全局类HashSet<User>变量 - 其中User具有SocketString(用户名)。然后,客户端发送给服务器的消息可以是(一系列)用户名,后跟实际消息。然后,服务器将遍历HashSet<User>并仅将实际消息发送给具有匹配用户名的Users

来源:我现在正在制作一个聊天应用程序,这就是我正在做的事情。这并不是说没有其他方式,甚至更好的方式。