Java 基于某个参数获取对另一个线程的引用
我正在开发一个Java客户机/服务器聊天应用程序,它允许局域网内的用户在他们之间聊天 在服务器应用程序中,我有一个主类,每当客户端连接到服务器时,它都会创建一个不同的线程。因此,基本上,我保持与每个运行在单独线程上的客户端的TCP连接 我在发送消息时遇到问题。当用户向服务器发送一条新消息+该消息的目标时,服务器必须找到与目标用户有连接的线程并将该消息发送给他。我该怎么做呢。我已经将每个线程与一个用户对象相关联,因此我需要执行类似findThreadByUser(用户)的操作,在获得引用后,只需调用发送消息的方法。我该怎么做 下面是实现Runnable的ConnectionHandler类的一些部分。我想访问该类的特定实例,更具体地说,是该类末尾的方法Java 基于某个参数获取对另一个线程的引用,java,multithreading,network-programming,Java,Multithreading,Network Programming,我正在开发一个Java客户机/服务器聊天应用程序,它允许局域网内的用户在他们之间聊天 在服务器应用程序中,我有一个主类,每当客户端连接到服务器时,它都会创建一个不同的线程。因此,基本上,我保持与每个运行在单独线程上的客户端的TCP连接 我在发送消息时遇到问题。当用户向服务器发送一条新消息+该消息的目标时,服务器必须找到与目标用户有连接的线程并将该消息发送给他。我该怎么做呢。我已经将每个线程与一个用户对象相关联,因此我需要执行类似findThreadByUser(用户)的操作,在获得引用后,只需调
sendToClient(String message)
(外部运行方法)。我尝试使用HashMap来存储用户和线程,但无法访问方法sendToClient(String message)
公共类ConnectionHandler实现可运行{
保护插座;
私有服务器数据服务器数据;
私人用户当前用户;
BufferedReader-inFromClient;
打印流输出到客户端;
字符串介词句;
细绳窥视;
字符串peerHostName;
公共连接处理程序(套接字socketToHandle、服务器数据服务器数据){
插座=插座手柄;
this.serverData=serverData;
INFOROMCLIENT=null;
outToClient=null;
currentUser=null;
client句子=”;
}
@凌驾
公开募捐{
peerIp=socket.getInetAddress().getHostAddress();
peerHostName=socket.getInetAddress().getHostName();
试一试{
outToClient=新的打印流(socket.getOutputStream(),true);
/*创建到套接字的读取流*/
INFOROMCLIENT=new BufferedReader(新的InputStreamReader(socket.getInputStream());
}捕获(IOEX异常){
Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE,null,ex);
System.out.println(“创建缓冲句柄时出错”);
}
System.out.println(“在“+peerIp+”处处理与客户端的连接”);
Runnable r1=新的Runnable(){
公开募捐{
while(true){
试一试{
/*通过套接字的输入缓冲区读取客户端消息*/
ClientSession=inFromClient.readLine();
}捕获(IOE异常){
System.out.println(socket.getInetAddress()+“-”+peerIp+“断开连接”);
打破
}
/*输出以筛选客户端接收的消息*/
System.out.println(“收到的消息:“+client句子”);
List processedClientSession=ClientMessageProcessor.process(clientSession);
if(processedClientSession.get(0).equals(新字符串(“登录”)){
String result=ServerActions.login(peerIp、peerHostName、processedClientSession.get(1)、serverData);
如果(结果等于(“成功”)){
currentUser=serverData.getUserByIP(peerIp);
println(“用户\”“+服务器操作.getUsers(服务器数据)+”“”);
}否则{
println(“错误\'”+结果+“\'”);
}
}else if(processedClientSession.get(0).equals(新字符串(“GETUSERS”)){
println(“用户\”“+服务器操作.getUsers(服务器数据)+”“”);
}else if(processedClientSession.get(0).equals(新字符串(“USERINFO”)){
}else if(processedClientSession.get(0).equals(新字符串(“消息”)){
ServerActions.sendMessage(currentUser/*.getUserName()*/,ProcessedClientSession.get(1),ProcessedClientSession.get(2),serverData);
}else if(processedClientSession.get(0).equals(新字符串(“注销”)){
}否则{
}
}
}
};
新线程(r1).start();
}
公用void sendToClient(字符串消息){
outToClient.println(消息);
}
}您可以查看这些问题以寻求帮助。
1.
2.
3.将客户端对象存储在
HashMap
中,用户名(将是唯一的)作为键,与之关联的线程作为值…`为什么不发送广播并让正确的客户端接受消息?为什么不能在每个UserObject
中创建一个字段thread
?为什么不保留一个映射,用户与对应的线程,并参考此映射以查找与特定user@SubinS因此,基本上您的意思是将用户与服务器数据类中的线程相关联,然后像这样调用线程:for(线程t:thread.getAllStackTraces().keySet())if(t.getId()==id)//send message
?感谢您的响应,如果OP需要线程,只需获得User
,将用户存储为值。您能看到我对问题所做的更改。正如你所说,我试过了,但我能访问的是基本的线程方法。但是,我想访问实现线程的类中的另一个方法。我在上面的问题上增加了全班的内容和解释。谢谢为什么?仅仅因为它是一个局域网聊天并不意味着你永远不想在多个子网上使用它(当然也不意味着你总是想把每一条私人消息发送给每一个客户端)。
public class ConnectionHandler implements Runnable {
protected Socket socket;
private ServerData serverData;
private User currentUser;
BufferedReader inFromClient;
PrintStream outToClient;
String clientSentence;
String peerIp;
String peerHostName;
public ConnectionHandler(Socket socketToHandle, ServerData serverData) {
socket = socketToHandle;
this.serverData = serverData;
inFromClient = null;
outToClient = null;
currentUser = null;
clientSentence = " ";
}
@Override
public void run() {
peerIp = socket.getInetAddress().getHostAddress();
peerHostName = socket.getInetAddress().getHostName();
try {
outToClient = new PrintStream(socket.getOutputStream(), true);
/* Create a reading stream to the socket */
inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException ex) {
Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Error creating buffered handles.");
}
System.out.println("Handling connection to client at " + peerIp + " --");
Runnable r1 = new Runnable() {
public void run() {
while (true) {
try {
/* Read client's message through the socket's input buffer */
clientSentence = inFromClient.readLine();
} catch (IOException e) {
System.out.println(socket.getInetAddress() + "-" + peerIp + " broke the connection.");
break;
}
/* Output to screen the message received by the client */
System.out.println("Message Received: " + clientSentence);
List<String> processedClientSentence = ClientMessageProcessor.process(clientSentence);
if (processedClientSentence.get(0).equals(new String("LOGIN"))) {
String result = ServerActions.login(peerIp, peerHostName, processedClientSentence.get(1), serverData);
if (result.equals("success")) {
currentUser = serverData.getUserByIP(peerIp);
outToClient.println("USERS \"" + ServerActions.getUsers(serverData) + "\"");
} else {
outToClient.println("ERROR \'" + result + "\'");
}
} else if (processedClientSentence.get(0).equals(new String("GETUSERS"))) {
outToClient.println("USERS \"" + ServerActions.getUsers(serverData) + "\"");
} else if (processedClientSentence.get(0).equals(new String("USERINFO"))) {
} else if (processedClientSentence.get(0).equals(new String("MESSAGE"))) {
ServerActions.sendMessage(currentUser/*.getUserName()*/, processedClientSentence.get(1), processedClientSentence.get(2), serverData);
} else if (processedClientSentence.get(0).equals(new String("LOGOUT"))) {
} else {
}
}
}
};
new Thread(r1).start();
}
public void sendToClient(String message) {
outToClient.println(message);
}