JAVA多线程服务器套接字

JAVA多线程服务器套接字,java,websocket,serversocket,java-threads,Java,Websocket,Serversocket,Java Threads,下面是接受客户端套接字连接并为每个连接分配线程的代码(JAVA) ServerSocket m_ServerSocket = new ServerSocket(); while (true) { java.util.Date today = Calendar.getInstance().getTime(); System.out.println(today+" - Listening to new connections...");

下面是接受客户端套接字连接并为每个连接分配线程的代码(JAVA

 ServerSocket m_ServerSocket = new ServerSocket();

 while (true) {
            java.util.Date today = Calendar.getInstance().getTime();
            System.out.println(today+" - Listening to new connections...");

           Socket clientSocket = m_ServerSocket.accept();
           ClientServiceThread cliThread = new ClientServiceThread( clientSocket);
           cliThread.start();
 }
假设连接了5个客户端,因此有5个线程正在运行

client 1: threadId 11
client 2: threadId 12
client 3 :threadId 13
client 4 :threadId 14
client 5 :threadId 15
假设其中一个客户机发送消息“kill-client1”,我希望结束客户机1的连接并杀死Id为11的线程,类似这样:

public void run() {
  try {
   BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
   PrintWriter out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

   while (running) {
    String clientCommand = in .readLine();

    if (clientCommand.equalsIgnoreCase("Kill-client1")) {
       // end the connection for client 1 & kill it's corresponding thread 11
    }
   }
 } catch (Exception e) {
  e.printStackTrace();
 }
 }

如何实现此目的?

要停止当前线程,请单击,然后从run()方法返回:

编辑:

例如,要关闭另一个线程,可以

  • 在线程之间共享clientID线程项的线程安全映射。当一个新的客户端连接时,您将为此客户端启动的线程存储在此映射中
  • 当Kill-client1命令进入时,您将从映射中获得对应于“client1”键的线程,并在此线程上调用ìinterrupt()
  • 在每个线程(例如client1线程)中,在循环的每次迭代中,检查thread.currentThread().isInterrupted()的值。如果为true,则关闭连接,从共享映射中删除线程,然后从
    run()
    方法返回

关键的一点是,你永远不会杀死另一个线程。您总是通过中断来请求线程停止,线程会检查其中断标志的值,以决定何时以及如何停止。只需终止循环:

   while (running) {
    String clientCommand = in .readLine();

    if (clientCommand.equalsIgnoreCase("Kill")) {
       running = false;
    }
   }
或:


不要忘记关闭
最后
块中的套接字。

只需跟踪所有客户端套接字和/或处理线程

Map<Integer,Socket> clients=new HashMap<>();

 while (true) {
            java.util.Date today = Calendar.getInstance().getTime();
            System.out.println(today+" - Listening to new connections...");

           Socket clientSocket = m_ServerSocket.accept();
           clients.put(generateNewClientId(),clientSocket);
           ClientServiceThread cliThread = new ClientServiceThread( clientSocket);
           cliThread.start();
 }
这将关闭给定的套接字,导致在处理线程时中断.readLine()中的
,从而完成线程


如果您跟踪线程,您可以设置“中断”标志,并在
while
条件下探测它,以便处理线程能够优雅地完成工作

您可以通过将
线程
存储到线程安全映射(因为它将由多个线程同时访问)中,并使用线程id作为键来实现这一点

// Map that will contain all my threads
Map<Long, ClientServiceThread> threads = new ConcurrentHashMap<>();

// Add to the constructor the instance of the class that manage the threads
ClientServiceThread cliThread = new ClientServiceThread(this, clientSocket);
// Add my new thread 
threads.put(cliThread.getId(), cliThread);
cliThread.start();
然后在主类中,您的方法如下所示:

public void interrupt(long threadId) {
    // Remove the thread from the map
    ClientServiceThread cliThread = threads.remove(threadId);
    if (cliThread != null) {
        // Interrupt the thread
        cliThread.interrupt();
    }
}
最后,您需要使类对中断敏感

try {
    ...
    while (!Thread.currentThread().isInterrupted()) {
        // My code here
    }
} finally {
    clientSocket.close();
}

我不希望线程自行终止,而是希望其他线程或父进程基于线程IDI终止它。我不希望线程自行终止,而是希望其他线程或父进程基于线程IDI终止它。你应该澄清你的问题,因为这还不清楚。线程如何根据“kill”命令知道要杀死哪个其他线程?是的,你是对的,让我编辑我的问题,但请帮助,因此你基本上希望客户端能够杀死其他客户端:)@Antoniossss是的,先生。这似乎让我更接近了,让我试试谢谢!如果这样做有效的话,我会接受答案。我决定使用你答案的逻辑组合&尼古拉斯·菲洛托安瑟。谢谢我决定结合使用you answer的逻辑和@Antoniosss的答案。谢谢
// Map that will contain all my threads
Map<Long, ClientServiceThread> threads = new ConcurrentHashMap<>();

// Add to the constructor the instance of the class that manage the threads
ClientServiceThread cliThread = new ClientServiceThread(this, clientSocket);
// Add my new thread 
threads.put(cliThread.getId(), cliThread);
cliThread.start();
String clientCommand = in.readLine().toLowerCase();
if (clientCommand.startsWith("kill")) {
    main.interrupt(Long.valueOf(clientCommand.substring(4).trim()));
}
public void interrupt(long threadId) {
    // Remove the thread from the map
    ClientServiceThread cliThread = threads.remove(threadId);
    if (cliThread != null) {
        // Interrupt the thread
        cliThread.interrupt();
    }
}
try {
    ...
    while (!Thread.currentThread().isInterrupted()) {
        // My code here
    }
} finally {
    clientSocket.close();
}