Tworzenie serwera socket, który umożliwia wiele połączeń za pośrednictwem wątków i Javy

Próbuję dostosować mój prosty serwer socket, aby mógł mieć wiele połączeń TCP, poprzez wielowątkowość, ale nie mogę go uruchomić. Mój kod do tej pory jest następujący, Nie jestem do końca pewien, dokąd się stąd udać:

import java.net.*;
import java.io.*;

public class DoSomethingWithInput implements Runnable {
   private final Socket clientSocket; //initialize in const'r
   public void run() {


     BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        String nextline;
        while ((nextline = in.readLine())!=null) {
           System.out.println(nextline);
        } //... close socket, etc.
    }
}


public class Socket{

  public Socket() {
}
@Override
public void run() {
  try {
    ServerSocket serverSocket = null;
    serverSocket = new ServerSocket(5432);
    for (;;) {
      ServerSocket serverSocket = null;
      serverSocket = new ServerSocket(5432);
      for (;;) {
        Socket clientSocket = null;
        clientSocket = serverSocket.accept();
        //delegate to new thread
        new Thread(new DoSomethingWithInput(clientSocket)).start();
      }
    }
  }catch (IOException e) {
   System.err.println("Could not listen on port: 5432.");
   System.exit(1);
}
}
}

Czy ktoś mógłby mi dać jakieś wskazówki, jak Mogę to zrobić i dlaczego moja obecna implementacja nie zadziała ? Przeglądałem porady w samouczku Java http://download.oracle.com/javase/tutorial/networking/sockets/examples/KKMultiServerThread.java tutaj, ale przykład, który tu podają, wydaje się wykorzystywać wiele zewnętrznych źródeł i klas, takich jak KnockKnockProtocol itp.itd.

Czy ktoś mógłby mi z tym pomóc?

Dziękuję bardzo!

Author: michael corrigan, 2011-02-24

2 answers

Problem polega na tym, że obecnie akceptujesz połączenie, ale potem natychmiast wykonujesz blokowanie odczytu, dopóki nie zostanie zamknięte:

// After a few changes...
Socket clientSocket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(
     clientSocket.getInputStream()));
String nextLine;
while ((nextLine = in.readLine()) != null) {
    System.out.println(nextline);
}

Oznacza to, że ten sam wątek, który akceptuje połączenie, próbuje obsłużyć połączenie. To nie pozwoli Ci korzystać z wielu połączeń w tym samym czasie.

Zamiast tego utwórz klasę (np. ConnectionHandler), która implementuje Runnable, a konstruktor przyjmuje Socket. Metoda run powinna obsługiwać połączenie. Następnie zmień Twój kod do:

Socket clientSocket = serverSocket.accept();
Runnable connectionHandler = new ConnectionHandler(clientSocket);
new Thread(connectionHandler).start();

To pozostawi twój" główny " wątek wolny, aby czekać na następne połączenie.

(nawiasem mówiąc, Klasa KnockKnockProtocol nie jest tak naprawdę "zewnętrzna" - jest częścią przykładu. Po prostu nie było jasne, że źródło jest tutaj...)

 50
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-24 19:51:47

Nie jesteś wielowątkowa. Tworzysz wątek, który wiąże się na porcie, a następnie odczytuje z dowolnego gniazda klienta, aż połączenie zostanie zamknięte.

Musisz przekazać gniazdo do nowego wątku i odczytać je.

public class DoSomethingWithInput implements Runnable {
   private final Socket clientSocket; //initialize in const'r
   public void run() {

        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        String nextline;
        while ((nextline = in.readLine())!=null) {
           System.out.println(nextline);
        } //... close socket, etc.
    }
}

//...
ServerSocket serverSocket = null;
serverSocket = new ServerSocket(5432);
for (;;) {
    Socket clientSocket = null;
    clientSocket = serverSocket.accept();
    //delegate to new thread
    new Thread(new DoSomethingWithInput(clientSocket)).start();
} //...
 18
Author: Mark Peters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-24 19:50:00