我必须为Uni做一个cluedo游戏,所以我们有一个Server类和正在连接的客户端。对于每个客户端连接,我们希望使用正在连接的客户端的套接字启动自己的ServerThread。此线程只是侦听传入的消息,并告诉服务器类将它们发送回客户端。 问题:每次新客户端连接时,他都会覆盖此ServerThread,因此始终只有一个ServerThread,我们希望每个客户端都有一个。我们在客户端之间发送JSON消息,现在ServerThread中的接收消息只从最后连接的套接字读取。我怎么解决这个问题?我在服务器中添加了我的接受方法我猜错误在那里,但可能在任何地方。谢谢你的帮助! 毛里求斯
服务器
public void accept() throws IOException{
while(true){
Socket socket = serverSocket.accept();
Runnable r = new ServerThreadHandler(socket);
Thread t = new Thread(r);
t.start();
}
}
ServerThreadHandler:
public class ServerThreadHandler implements Runnable {
static Socket socket=null;
protected User client;
//private static int i;
private static BufferedReader in;
private static OutputStreamWriter out;
public void createUser(String nick, String group, String[] ext) throws IOException{
client = new User(nick, group, ext, null, false, 0, false, socket, socket.getPort());
}
/**
* constructor-Method
* @param socketS
*/
ServerThreadHandler(Socket socketS){
socket = socketS;
}
public void run(){
Server.setThreadList(socket);
in = createReader();
out = createWriter();
//and so on...
}
}
答案 0 :(得分:2)
您的代码片段中提到的逻辑肯定会创建与no一样多的线程。正在连接的客户。
但是,可能的原因可能是,因为ServerThreadHandler中的Socket变量是静态的,所有创建的后续线程都会覆盖相同的套接字变量,导致先前创建的使用套接字变量的线程出现问题。
你应该考虑使用非静态变量作为ServerThreadHandler中的Socket,因为任何可运行的类都应该保持一个状态,不应该使用静态套接字。
根据我对你的问题的理解, createUser方法是ServerThreadHandler的实例方法。因此,您必须已创建ServerThreadHandler实例以从另一个类调用createUser。因此,即使它是实例变量,您也可以访问套接字变量。
答案 1 :(得分:1)
Socket
成员变量应该是非静态的。与读者和作家一样。
永远不要将变量设为静态,除非你有充分的理由这样做并理解后果。
答案 2 :(得分:1)
不幸的是,代码存在许多设计缺陷:
我可以建议的最快的解决方法是删除User
类并移动Handler类中的所有内容(或副verca?)
也会变换所有变量non-static
static Socket socket=null;
protected User client;
//private static int i;
private static BufferedReader in;
private static OutputStreamWriter out;
他们应该是:
Socket socket=null;
protected User client;
//private int i;
private BufferedReader in;
private OutputStreamWriter out;