Java sockets: plusieurs threads client sur le même port sur la même machine?

je suis nouveau à la programmation de Socket en Java et j'essayais de comprendre si le code ci-dessous n'est pas une mauvaise chose à faire. Ma question Est:

puis-je avoir plusieurs clients sur chaque thread essayant de se connecter à une instance du serveur dans le même programme et s'attendre à ce que le serveur Lise et écrive des données avec isolation entre les clients"

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

maintenant je peux avoir plusieurs instances Client sur différents threads essayant de me connecter sur le même port du courant de la machine?

Par exemple,

   Server s = new Server("localhost", 1234);
   s.start();
   Client[] c = new Client[10];
   for (int i = 0; i < c.length; ++i)
   {
        c.start();
   }
17
demandé sur espcorrupt 2010-05-12 22:26:56

6 réponses

Oui, mais un seul client sera en mesure de se connecter par l'exécution du thread.

Vous pouvez simplement mettre votre serveur run() à l'intérieur d'une boucle while true pour permettre à plusieurs clients de se connecter. Selon l'exécuteur, ils s'exécuteront en série ou en parallèle.

   public class Server extends Thread  
   {  
       ...  
       void run()  
       {  
           while(true){
              // serverSocket on "localhost", 1234  
              Socket clientSock = serverSocket.accept();  
              executor.execute(new ClientWorker(clientSock));  
           }
       }  
   } 
9
répondu patros 2010-05-12 18:36:57

tant que vous n'avez qu'un seul objet essayant de lier le port pour écouter, alors il n'y a aucun problème avec plusieurs clients se connectant.

3
répondu Jherico 2010-05-12 18:30:00

Dans cet exemple,Server accepte et gère une connexion client à la fois. Vous pouvez avoir autant d' Client s comme vous voulez essayer de se connecter, mais seulement un à la fois sera traitée.

il n'est pas évident que votre logique exécuteur soit multithread, puisque vous n'avez pas fourni l'implémentation. Si l'exécuteur délègue à un threadpool ou quelque chose comme ça, vous devez vous assurer que votre ClientWorker est thread-safe, vous aurez plusieurs instances l'exécution en parallèle.

je suppose bien sûr que votre Client est thread-safe, car votre question est seulement en ce qui concerne les Server.

1
répondu danben 2010-05-12 18:33:33

Oui, peu importe que vos clients soient locaux ou éloignés. La chose importante dans votre exemple est que ClientWorker est thread-safe, car votre serveur aura plusieurs instances de cette classe (une pour chaque connexion client).

0
répondu G__ 2010-05-12 18:33:05

. Pour commencer:

vous pouvez accepter plus de clients avec un seul serversocket, parce que vous n'en acceptez qu'un seul dans le run-méthode. Vous avez juste à appeler accept() une seconde fois.

puis, vous dans votre boucle for: d'abord vous devez créer à chaque fois un nouveau Client objet. Alors vous pouvez appeler c[i].start(); et non c.start().

maintenant je peux avoir plusieurs clients instances sur différents threads relier sur le même port du actuel de la machine?

Oui, vous pouvez. Il suffit de créer de nouveaux fils et de les exécuter. Cela devrait fonctionner parfaitement.

s'attendre à ce que le serveur Lise et écrive données avec isolement entre les clients

vous pouvez utiliser votre expérience des techniques de base de IO comme avec file-io:

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!");

et pour la lecture Utiliser un lecteur tampon.

0
répondu Martijn Courteaux 2010-05-12 18:37:41

Vous pouvez essayer quelque chose sur ces lignes

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
répondu Kashif 2017-10-04 12:18:18