简体   繁体   English

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

[英]Socket Server - Pass client messages through

I am creating a chat client. 我正在创建一个聊天客户端。 I have multiple clients connecting but I am having a hard time getting them to talk to each other. 我有多个客户端连接,但是我很难让他们彼此交谈。 How do I get the server to send the message incoming from client1 to the rest of the clients without client1 having an echo? 如何让服务器将从client1传入的消息发送到其余的client,而client1没有回声? I haven't discovered any way to identify each client. 我还没有发现任何识别每个客户的方法。

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

The simplest way to do it is have an Array or list of Sockets, and add to it every time a new client connects/subtract when client leaves. 最简单的方法是拥有一个Array或Sockets列表,并在客户端离开时每次新客户端连接/减去时将其添加到其中。

Then when a message is received, loop through that array/list and send message to other clients. 然后,当收到消息时,遍历该数组/列表,然后将消息发送给其他客户端。 (make sure to check the client you are on against the current client in list so you dont send message to the client that sent it to server) (确保对照列表中的当前客户端检查您所在的客户端,以免将消息发送到将其发送到服务器的客户端)

While this is fine on a small scale, it will cause problem on a large scale as you have to loop through a large list each time a new message is received. 虽然这在小范围内很好,但在每次收到新消息时都必须遍历大列表,这会在很大程度上导致问题。

to have chatRooms or something, you can have a multidimensional array ( Array[room][socket] ) then you can do loop through certain rooms and only send to those clients, or loop through all, etc. 要拥有chatRooms或类似的东西,您可以拥有一个多维数组( Array[room][socket] ),然后您可以遍历某些会议室并仅发送给那些客户端,或遍历所有客户端,依此类推。

To send to specific users only, you can have a User.java class that has a username and a socket in it. 要仅发送给特定用户,可以有一个User.java类,其中包含用户名和套接字。 then, instead of doing an array of sockets, use an array of users and in your loop, check username and only send to the required users. 然后,不使用套接字数组,而是使用用户数组,并在您的循环中检查用户名并仅发送给所需的用户。

Flow: UserA connects to server, sends username to be bob server recieves connections, makes new User object, sets username to bob and sets socket to users socket, then adds that User object to User[] 流:UserA连接到服务器,发送用户名作为bob服务器接收连接,建立新的User对象,将username设置为bob并将socket设置为users套接字,然后将该User对象添加到User[]

UserB connects to server, sends username john same deal, server makes new user object etc etc. UserB连接到服务器,向用户名john发送相同的交易,服务器创建新的用户对象等。

john sends a message to server and tells it to only send the message to bob Server loops through User[] and checks username of them, if username matches bob server calls getSocket on that user object, this returns the socket connection for that user. john向服务器发送一条消息,并告诉它仅将消息发送给bob服务器循环通过User[]并检查它们的用户名,如果用户名与该用户对象上的bob服务器调用getSocket匹配,则返回该用户的套接字连接。 server then gets the outputStream of that socket, and creates a printwriter with it. 然后,服务器获取该套接字的outputStream,并使用该套接字创建一个printwriter。 the it sends the message received from john through the newly create printwriter. 它通过新创建的printwriter发送从john收到的消息。

If your question is how to send/receive messages over a socket, the following is one way to do it. 如果您的问题是如何通过套接字发送/接收消息,则以下是一种方法。

To send: 发送:

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

And to read: 并阅读:

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
}

You should see Socket#getOutputStream() and Socket#getInputStream() , and then use methods in the DataInputStream and DataOutputStream class. 您应该看到Socket#getOutputStream()Socket#getInputStream() ,然后在DataInputStreamDataOutputStream类中使用方法。 input.ava input.ava

As for your other question, if you want a client to be able to send messages to specific other client(s), the client must know exactly which client(s) it wants to send the message to. 至于您的其他问题,如果您希望客户端能够将消息发送到特定的其他客户端,则该客户端必须确切知道要将消息发送至哪个客户端。 When the client sends a message to the server, that information has to be part of the message. 当客户端向服务器发送消息时,该信息必须是消息的一部分。 The server would use that to selectively send the message to specific Sockets . 服务器将使用它选择性地将消息发送到特定的Sockets

There would have to be a system in place of course. 当然必须要有一个系统。 For example, for a chat app each client might have a username. 例如,对于聊天应用程序,每个客户端可能都有一个用户名。 You could have a global class HashSet<User> variable - where a User has a Socket and a String (username). 您可能有一个全局类HashSet<User>变量- User具有SocketString (用户名)。 The client's message to the server could then be a (series of) username(s) followed by the actual message. 客户端发送给服务器的消息可以是一个(一系列)用户名,后跟实际的消息。 The server would then iterate through the HashSet<User> and send the actual message only to Users with matching usernames. 然后,服务器将遍历HashSet<User>并将实际消息仅发送给具有匹配用户名的Users

Source: I'm making a chat app right now as well, and this is how I'm doing it. 资料来源:我现在也在制作一个聊天应用程序,这就是我的做法。 That's not to say there aren't other ways, or even better ways. 这并不是说没有其他方法,甚至没有更好的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 客户端无法将消息发送到服务器Java套接字 - Client unable to send messages to server Java socket 目标C套接字服务器未收到Java套接字客户端消息 - Objective C Socket Server does not receive Java Socket Client Messages 从客户端套接字向服务器套接字发送消息时出现问题 - Problem when sending messages from client socket to server socket 如何通过套接字传递FTP服务器的目录结构,并使用JTree在客户端的GUI中显示它 - How to pass an FTP server's directory structure through a socket and display it in Client's GUI using JTree Java客户端套接字:无法从服务器接收消息到客户端 - Java client-socket:Cannot receive messages from server to client 如何在Java Server Client中通过套接字传递对象 - How to pass object by socket in java Server Client 无法通过客户端/服务器程序的套接字连接 - Cannot connect through socket for client/server program 使用DataOutputStream向Server Socket写消息到Client Socket的消息仅在关闭Client Socket后才发送,为什么? - Writing messages to client socket using DataOutputStream to Server Socket only sent after closing the Client Socket why? 客户端通过套接字从服务器接收消息时出现一些问题 - some problem when client receive messages from server though socket Android 客户端套接字不向外部服务器发送或接收消息 - Android Client Socket not sending nor recieving messages to external server
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM