2016-10-05 3 views
2

Es folgt der Code (JAVA), der eine Client-Socket-Verbindung akzeptiert und jeder Verbindung einen Thread zuweist.JAVA Multithread-Server-Sockets

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(); 
} 

Angenommen, es sind 5 Clients verbunden, daher werden 5 Threads ausgeführt.

client 1: threadId 11 
client 2: threadId 12 
client 3 :threadId 13 
client 4 :threadId 14 
client 5 :threadId 15 

Es sei einer der Clients sendet eine Nachricht "kill-client1", ich Ende Client 1 die Verbindung wünschen und den Faden mit Id 11, so etwas wie dieses töten:

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(); 
} 
} 

Wie kann ich das erreichen?

+0

so wollen, dass Sie im Grunde machen für Kunden in der Lage sein, andere – Antoniossss

+0

@Antoniossss Ja, Sir :) Kunden zu töten. –

Antwort

1

Behalten Sie einfach alle Client-Sockets und/oder die Handhabung von Threads im Auge.

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(); 
} 

Und dann, wenn Sie einfach

tun
{ 
    if (clientCommand.equalsIgnoreCase("Kill")) { 
     Socket socket=clients.get(idToShutDown);// get required id somehow (from request??) 
     socket.close(); 
    } 
} 

Diese Buchse resultierenden gegeben schließen in.readLine() Gewinde im Umgang damit Fäden brechen beenden.

Wenn Sie die Threads verfolgen, können Sie "Interrupt" -Flag setzen und es in while Zustand testen, so dass Ihr Handler Thread ordnungsgemäß arbeiten kann.

+0

zu töten Scheint dies bringt mich näher, lass mich versuchen Danke! Wenn das funktioniert, akzeptiere ich die Antwort. –

+0

Ich habe beschlossen, eine Kombination aus Ihnen Antwort Logik und @ Nicolas Filottoanswer zu verwenden. Vielen Dank ! –

0

den aktuellen Thread zu beenden, Sie close the socket und Rückkehr aus der run() Methode:

if (clientCommand.equalsIgnoreCase("Kill")) { 
    clientSocket.close(); 
    return; 
} 

EDIT:

anderen Thread zu schließen, kann man zum Beispiel

  • teilen Sie eine thread-sichere Karte von clientID-Thread-Einträge zwischen Threads. Wenn ein neuer Client eine Verbindung herstellt, speichern Sie den für diesen Client in dieser Map gestarteten Thread
  • , wenn ein Befehl Kill-client1 eingeht, erhalten Sie den Thread, der den Schlüssel "client1" aus der Map enthält, und rufen "interrupt()" auf Faden.
  • In jedem Thread (z. B. dem Thread client1) überprüfen Sie bei jeder Iteration der Schleife den Wert von Thread.currentThread(). IsInterrupted(). Wenn dies der Fall ist, schließen Sie die Verbindung, entfernen den Thread aus der freigegebenen Map und kehren von der Methode run() zurück.

Der entscheidende Punkt ist, dass Sie nie einen anderen Thread töten. Sie fordern immer einen Thread an, ihn anzuhalten, indem Sie ihn unterbrechen, und der Thread überprüft den Wert seines Interrupt-Flags, um zu entscheiden, wann und wie er gestoppt werden muss.

+0

Ich möchte nicht, dass der Thread sich selbst tötet, sondern ich möchte andere Threads oder vielleicht den übergeordneten Prozess, um es basierend auf Thread-ID –

+0

zu töten Sie sollten Ihre Frage dann klären, weil das nicht klar ist. Wie würde der Thread anhand des Befehls "Kill" wissen, welcher andere Thread zu töten ist? –

+0

Ja, Sie haben Recht, lassen Sie mich meine Frage bearbeiten, aber bitte helfen –

0

beenden Sie einfach die Schleife:

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

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

oder:

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

    if (clientCommand.equalsIgnoreCase("Kill")) { 
     break; 
    } 
    } 

Und vergessen Sie nicht die Steckdose in finally Block zu schließen.

+0

Ich möchte nicht, dass der Thread sich selbst tötet, eher möchte ich andere Threads oder vielleicht den Elternprozess, um es basierend auf Thread-ID –

1

Sie könnten das tun, indem Sie Ihre Threads in eine Thread-sichere Karte speichert mit der Thread-ID als Schlüssel

// 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(); 

Dann (wie es von mehreren Threads gleichzeitig zugegriffen wird), wenn ein Kill gestartet

String clientCommand = in.readLine().toLowerCase(); 
if (clientCommand.startsWith("kill")) { 
    main.interrupt(Long.valueOf(clientCommand.substring(4).trim())); 
} 

Dann in der Hauptklasse Ihre Methode würde wie folgt aussehen:

public void interrupt(long threadId) { 
    // Remove the thread from the map 
    ClientServiceThread cliThread = threads.remove(threadId); 
    if (cliThread != null) { 
     // Interrupt the thread 
     cliThread.interrupt(); 
    } 
} 

Schließlich müssen Sie Ihre Klasse ClientServiceThread empfindlich auf Unterbrechungen

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

Ich habe beschlossen, eine Kombination aus Ihnen Antwort-Logik und @ Antoniossss Antwort verwenden. Vielen Dank ! –