嘿伙计们,我最近刚刚收到插座,但遇到了向多个客户发帖的问题。我已经使它多线程处理这个并且我试图保存服务器需要在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) {
}
}
}
}
}
答案 0 :(得分:1)
name
似乎总是为空,因此您继续使用相同的键(null),这可以解释为什么地图中只有一个用户。
另请注意,HashMap不是线程安全的 - 除非您在从线程访问地图时添加某种形式的同步,否则可能会产生令人惊讶的结果。
您可以使用线程安全映射,例如ConcurrentHashMap。