wake-up-neo.com

Java-Sockets: Mehrere Client-Threads auf demselben Port auf demselben Computer?

Ich bin neu in der Socket-Programmierung in Java und habe versucht zu verstehen, ob der folgende Code nicht falsch ist. Meine Frage ist:

Kann ich mehrere Clients in jedem Thread haben, die versuchen, eine Verbindung zu einer Serverinstanz im selben Programm herzustellen, und erwarten, dass der Server Daten mit Isolation zwischen Clients liest und schreibt? "

public class Client extends Thread
{
    ...
    void run()
    {
        Socket socket = new Socket("localhost", 1234);
        doIO(socket);  
    }
}

public class Server extends Thread
{
    ...
    void run()
    {
        // serverSocket on "localhost", 1234
        Socket clientSock = serverSocket.accept();
        executor.execute(new ClientWorker(clientSock));
    }
}

Kann ich jetzt mehrere Client-Instanzen in verschiedenen Threads haben, die versuchen, eine Verbindung zum gleichen Port des aktuellen Computers herzustellen?

Zum Beispiel,

   Server s = new Server("localhost", 1234);
   s.start();
   Client[] c = new Client[10];
   for (int i = 0; i < c.length; ++i)
   {
        c.start();
   }
17
espcorrupt

Ja, jedoch kann nur ein Client pro Thread-Ausführung eine Verbindung herstellen, wie geschrieben.

Sie können Ihren Server mit run () in eine while-True-Schleife einbinden, damit sich mehrere Clients verbinden können. Je nach Executor werden sie entweder in Reihe oder parallel ausgeführt.

   public class Server extends Thread  
   {  
       ...  
       void run()  
       {  
           while(true){
              // serverSocket on "localhost", 1234  
              Socket clientSock = serverSocket.accept();  
              executor.execute(new ClientWorker(clientSock));  
           }
       }  
   } 
9
patros

Solange Sie nur ein Objekt haben, das versucht, den Port für das Abhören zu binden, gibt es kein Problem, wenn mehrere Clients eine Verbindung herstellen. 

3
Jherico

In diesem Beispiel akzeptiert und verarbeitet Ihre Server jeweils eine Clientverbindung. Sie können so viele Clients haben, wie Sie möchten, um eine Verbindung herzustellen, aber es wird jeweils nur eine davon behandelt.

Es ist nicht ersichtlich, ob Ihre Executor-Logik Multithreading ist, da Sie die Implementierung nicht bereitgestellt haben. Wenn der Executor an einen Threadpool oder etwas Ähnliches delegiert, müssen Sie sicherstellen, dass Ihre ClientWorker threadsicher ist, da mehrere Instanzen parallel ausgeführt werden.

Ich gehe natürlich davon aus, dass Ihre Client auch Thread-sicher ist, da Ihre Frage nur die Server betrifft.

1
danben

Ja, es spielt keine Rolle, ob Ihre Clients lokal oder remote sind. In Ihrem Beispiel ist es wichtig, dass ClientWorker Thread-sicher ist, da Ihr Server über mehrere Instanzen dieser Klasse verfügt (eine für jede Clientverbindung).

0
G__

Sie können etwas auf diesen Zeilen versuchen

public class MultiThreadServer extends Application {
  // Text area for displaying contents
  private TextArea ta = new TextArea();

  // Number a client
  private int clientNo = 0;

  @Override // Override the start method in the Application class
  public void start(Stage primaryStage) {
    // Create a scene and place it in the stage
    Scene scene = new Scene(new ScrollPane(ta), 450, 200);
    primaryStage.setTitle("MultiThreadServer"); // Set the stage title
    primaryStage.setScene(scene); // Place the scene in the stage
    primaryStage.show(); // Display the stage

    new Thread( () -> {
      try {
        // Create a server socket
        ServerSocket serverSocket = new ServerSocket(8000);
        ta.appendText("MultiThreadServer started at " 
          + new Date() + '\n');

        while (true) {
          // Listen for a new connection request
          Socket socket = serverSocket.accept();

          // Increment clientNo
          clientNo++;

          Platform.runLater( () -> {
            // Display the client number
            ta.appendText("Starting thread for client " + clientNo +
              " at " + new Date() + '\n');

            // Find the client's Host name, and IP address
            InetAddress inetAddress = socket.getInetAddress();
            ta.appendText("Client " + clientNo + "'s Host name is "
              + inetAddress.getHostName() + "\n");
            ta.appendText("Client " + clientNo + "'s IP Address is "
              + inetAddress.getHostAddress() + "\n");
          });

          // Create and start a new thread for the connection
          new Thread(new HandleAClient(socket)).start();
        }
      }
      catch(IOException ex) {
        System.err.println(ex);
      }
    }).start();
  }

  // Define the thread class for handling new connection
  class HandleAClient implements Runnable {
    private Socket socket; // A connected socket

    /** Construct a thread */
    public HandleAClient(Socket socket) {
      this.socket = socket;
    }

    /** Run a thread */
    public void run() {
      try {
        // Create data input and output streams
        DataInputStream inputFromClient = new DataInputStream(
          socket.getInputStream());
        DataOutputStream outputToClient = new DataOutputStream(
          socket.getOutputStream());

        // Continuously serve the client
        while (true) {
          // Receive radius from the client
          double radius = inputFromClient.readDouble();

          // Compute area
          double area = radius * radius * Math.PI;

          // Send area back to the client
          outputToClient.writeDouble(area);

          Platform.runLater(() -> {
            ta.appendText("radius received from client: " +
              radius + '\n');
            ta.appendText("Area found: " + area + '\n');
          });
        }
      }
      catch(IOException e) {
        ex.printStackTrace();
      }
    }
  }

  /**
   * The main method is only needed for the IDE with limited
   * JavaFX support. Not needed for running from the command line.
   */
  public static void main(String[] args) {
    launch(args);
  }
}
0
Kashif

So. Beginnen:

Sie können mehrere Clients mit einem Serversocket akzeptieren, da Sie nur einen in der run- Methode akzeptieren. Sie müssen nur noch ein zweites Mal accept() aufrufen.

Dann sind Sie in Ihrer for-Schleife: Zuerst müssen Sie jedes Mal ein neues Client-Objekt erstellen. Dann können Sie c[i].start(); und nicht c.start() aufrufen.

Kann ich jetzt mehrere Client - Instanzen auf verschiedenen Threads haben, die versuchen, An demselben Port des aktuellen Computers anzuschließen?

Ja, du kannst. Erstellen Sie einfach neue Threads und führen Sie sie aus. Das sollte perfekt funktionieren.

erwarten, dass der Server Daten mit Isolierung zwischen Clients liest und schreibt

Sie können Ihre Erfahrung mit den grundlegenden IO-Techniken wie mit file-io verwenden:

OutputStream os = socket.getOutputStream();
PrintStream pw = new PrintStream(os, true); // Or PrintWriter, I don't know what the best one is.
pw.println("Hello, other side of the connection!");

Und zum Lesen verwenden Sie einen BufferedReader. 

0