新套接字连接时线程被覆盖 (Server/Client) 多线程 java
thread overwritten when new socket connects (Server/Client) multithread java
我必须为 Uni 做一个线索游戏,所以我们有一个服务器 class 和正在连接的客户端。对于每个连接的客户端,我们希望使用正在连接的客户端的套接字启动自己的 ServerThread。这个线程只是监听传入的消息并告诉服务器 class 将它们发送回客户端。
问题:每次新客户端连接时,他都会覆盖此 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();
}
}
服务器线程处理器:
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...
}
}
您的代码片段中提到的逻辑肯定会创建与编号一样多的线程。正在连接的客户端数。
然而,可能的原因可能是,由于 ServerThreadHandler 中的 Socket 变量是静态的,所有后续创建的线程都会覆盖相同的套接字变量,导致先前创建的使用套接字变量的线程出现问题。
您应该考虑在 ServerThreadHandler 中为 Socket 使用非静态变量,因为任何可运行的 class 都应该保持状态而不应该使用静态套接字。
根据我从你的问题中了解到的,
createUser方法是ServerThreadHandler的一个实例方法。因此,您必须创建 ServerThreadHandler 的实例才能从另一个 class 调用 createUser。因此,即使它是实例变量,您也可以访问套接字变量。
Socket
成员变量应该是非静态的。同上 reader 和作家。
永远不要将变量设置为静态,除非你有充分的理由这样做并理解后果。
不幸的是代码有很多设计缺陷:
我建议的最快解决方法是删除 User
class 并移动 Handler class 中的所有内容(反之亦然?)
也让你所有的变量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;
我必须为 Uni 做一个线索游戏,所以我们有一个服务器 class 和正在连接的客户端。对于每个连接的客户端,我们希望使用正在连接的客户端的套接字启动自己的 ServerThread。这个线程只是监听传入的消息并告诉服务器 class 将它们发送回客户端。 问题:每次新客户端连接时,他都会覆盖此 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();
}
}
服务器线程处理器:
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...
}
}
您的代码片段中提到的逻辑肯定会创建与编号一样多的线程。正在连接的客户端数。
然而,可能的原因可能是,由于 ServerThreadHandler 中的 Socket 变量是静态的,所有后续创建的线程都会覆盖相同的套接字变量,导致先前创建的使用套接字变量的线程出现问题。
您应该考虑在 ServerThreadHandler 中为 Socket 使用非静态变量,因为任何可运行的 class 都应该保持状态而不应该使用静态套接字。
根据我从你的问题中了解到的, createUser方法是ServerThreadHandler的一个实例方法。因此,您必须创建 ServerThreadHandler 的实例才能从另一个 class 调用 createUser。因此,即使它是实例变量,您也可以访问套接字变量。
Socket
成员变量应该是非静态的。同上 reader 和作家。
永远不要将变量设置为静态,除非你有充分的理由这样做并理解后果。
不幸的是代码有很多设计缺陷:
我建议的最快解决方法是删除 User
class 并移动 Handler class 中的所有内容(反之亦然?)
也让你所有的变量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;