gpt4 book ai didi

java - 向多个客户发布问题

转载 作者:行者123 更新时间:2023-12-01 14:59:36 25 4
gpt4 key购买 nike

嘿伙计们,我最近刚刚掌握了套接字的窍门,但在向多个客户端发布消息时遇到了问题。我已经将其设置为多线程来处理此问题,并尝试将服务器需要发送到的所有客户端数据保存在 HashMap 中,但是在循环并添加到 HashMap 中时。它似乎只添加了一个人。这是代码..

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

public class HostMain extends Thread {

/**
* The set of all names of clients in the chat room. Maintained
* so that we can check that new clients are not registering name
* already in use.
*/
private static HashMap<String, ConnectedUsers> users = new HashMap<String, ConnectedUsers>();

public HostMain() throws IOException
{

}

public void run()
{
try
{
System.err.println("SERVER:The chat server is running.");
ServerSocket listener = new ServerSocket(PORT);
System.err.println("SERVER:socket created");
Constants.getInstance().getStatusLabel().setText("Server is running. Join when ready");
try {
while (true) {

System.err.println("SERVER:New handler being created");
new Handler(listener.accept()).start();

}
} finally {
listener.close();
}
}
catch(Exception e)
{
Constants.getInstance().getStatusLabel().setText("SERVER:A HOST IS ALREADY RUNNING ON THIS PORT!");
System.err.println("SERVER:A HOST IS ALREADY RUNNING ON THIS PORT!");
}
}
/**
* The port that the server listens on.
*/
private static final int PORT = 1337;




/**
* The appplication main method, which just listens on a port and
* spawns handler threads.
*/

/**
* A handler thread class. Handlers are spawned from the listening
* loop and are responsible for a dealing with a single client
* and broadcasting its messages.
*/
private static class Handler extends Thread {
private String name;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private ObjectInputStream oin;
private ObjectOutputStream oout;
/**
* Constructs a handler thread, squirreling away the socket.
* All the interesting work is done in the run method.
*/
public Handler(Socket socket) {
this.socket = socket;
}

/**
* Services this thread's client by repeatedly requesting a
* screen name until a unique one has been submitted, then
* acknowledges the name and registers the output stream for
* the client in a global set, then repeatedly gets inputs and
* broadcasts them.
*/
public void run() {
try {

// Create object streams for the socket.
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
oin = new ObjectInputStream(socket.getInputStream());
oout = new ObjectOutputStream(socket.getOutputStream());


//add socket to a list
users.put(name,new ConnectedUsers(name,oout));
System.err.println(users.size());
// Accept messages from this client and broadcast them.
// Ignore other clients that cannot be broadcasted to.
while (true) {

Object obj = oin.readObject();
Messages message = (Messages)obj;
if(obj.getClass().equals(Messages.class))
{
for(Map.Entry<String, ConnectedUsers> entry:users.entrySet())
{

ConnectedUsers user = entry.getValue();
user.objectWriter.writeObject(message);
}

}

}
} catch (IOException | ClassNotFoundException e) {
System.out.println(e);
} finally {
// This client is going down! Remove its name and its print
// writer from the sets, and close its socket.
if (name != null) {
users.remove(name);
}
try {
socket.close();
} catch (IOException e) {
}
}
}
}
}

最佳答案

name 似乎始终为 null,因此您继续使用相同的键 (null),这可以解释为什么您的 map 中只有一个用户。

另请注意,HashMap 不是线程安全的 - 除非您在从线程访问映射时添加某种形式的同步,否则可能会产生令人惊讶的结果。

您可以使用线程安全映射,例如 ConcurrentHashMap。

关于java - 向多个客户发布问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13870322/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com