2 votes

Threading Java dans les sockets TCP et serveur

J'ai écrit les deux lignes suivantes

ServerSocket mobCom = new ServerSocket(9846);
Socket server = mobCom.accept();

Je veux qu'une nouvelle connexion TCP soit créée et que cette connexion soit gérée par un nouveau thread. Par exemple, le code ci-dessus crée un socket serveur. Et il y a plusieurs clients. Chaque fois qu'un client se connecte à un serveur, un nouveau thread peut être créé pour répondre aux demandes provenant de ce client particulier. Comment puis-je implémenter la même chose ?

EDIT

Je souhaite également limiter un pool de threads à 10 utilisateurs. Et si d'autres utilisateurs se présentent, je veux leur envoyer un message d'erreur sans traiter d'autres demandes de leur part.

0voto

maggu Points 584

Vous pouvez obtenir les résultats souhaités en utilisant la méthode concurrente de java util. SynchronousQueue . Créez un nombre fixe de travailleurs. Utilisez le prendre pour lancer la lecture du bloc sur la SynchronousQueue. Ainsi, si tous les travailleurs ont pris un travail chacun et sont occupés à les traiter (en communiquant avec le socket), il n'y aura pas de lecture de la SynchronousQueue et donc un appel de type offre vers la file d'attente synchrone échouera. En vérifiant cet échec (ce qui signifie que tous les travailleurs à nombre fixe sont occupés, aucun ne s'accroche à la file d'attente maintenant), rejeter la ou les demandes suivantes.

Exemple de code dans les lignes suivantes [Non testé - Les exceptions ont été évitées pour des raisons de brièveté, veuillez les modifier selon vos besoins].

public class BoundedServer 
{
    public static void main(String[] args) 
    {
        /**
         * Port to serve
         */
        final int port = 2013;

        /**
         * Max Workers
         */
        final int maxworkers = 10; 

        /**
         * The server socket.
         */
        ServerSocket mServerSocket = null;

        /**
         * Queue of work units to process if there is a worker available.
         */
        final SynchronousQueue<WorkUnit> mQueueToProcess = new SynchronousQueue<WorkUnit>();

        /**
         * Queue of work units to reject if there is no current worker available.
         */
        final LinkedBlockingQueue<WorkUnit> mQueueToReject = new LinkedBlockingQueue<WorkUnit>(); 

        /**
         * A thread pool to handle the work.
         */
        final ExecutorService communicationservice = Executors.newFixedThreadPool(maxworkers);

        /**
         * Let a single thread take care of rejecting the requests when needed to do so.
         */
        final ExecutorService rejectionservice = Executors.newSingleThreadExecutor();

        try 
        {
            Runnable communicationlauncher = new Runnable() 
            {
                public void run() 
                {
                    try
                    {
                        /**
                         * Set of workers to handle the work.
                         */
                        final CommunicationWorker[] workers = new CommunicationWorker[maxworkers];

                        communicationservice.invokeAll(Arrays.asList(workers));
                    }
                    finally
                    {
                        communicationservice.shutdown();
                    }
                }
            };

            new Thread(communicationlauncher).start();

            Runnable rejectionlauncher = new Runnable() 
            {
                public void run() 
                {
                    try
                    {
                        RejectionWorker rejectionworker = new RejectionWorker(mQueueToReject);

                        rejectionservice.submit(rejectionworker);
                    }
                    finally
                    {
                        rejectionservice.shutdown();
                    }
                }
            };
            new Thread(rejectionlauncher).start();

            mServerSocket = new ServerSocket(port);

            while(true)
            {
                WorkUnit work = new WorkUnit(mServerSocket.accept());

                if(!mQueueToProcess.offer(work))
                {
                    mQueueToReject.add(work);
                }
            }
        } 
        finally
        {
            try
            {
                mServerSocket.close();
            }
        }
    }
}

public class WorkUnit 
{
    private Socket mSocket = null;

    public WorkUnit(Socket socket) 
    {
        super();
        this.setSocket(socket);
    }

    public Socket getSocket() {
        return mSocket;
    }

    public void setSocket(Socket mSocket) {
        this.mSocket = mSocket;
    }
}

public class CommunicationWorker 
implements Callable<Boolean> 
{
    private SynchronousQueue<WorkUnit> mQueueToProcess;

    public CommunicationWorker(SynchronousQueue<WorkUnit> queueToProcess) 
    {
        super();
        this.mQueueToProcess = queueToProcess;
    }

    @Override
    public Boolean call() throws Exception 
    {
        while(true)
        {
            WorkUnit work = mQueueToProcess.take();

            Socket socket = work.getSocket();

            // Code to handle socket communication and closure.
            // Once the communication is finished, this thread will get blocked to mQueueToProcess.
        }
    }
}

public class RejectionWorker 
implements Callable<Boolean> 
{
    private LinkedBlockingQueue<WorkUnit> mQueueToReject;

    public RejectionWorker(LinkedBlockingQueue<WorkUnit> queueToReject) 
    {
        super();
        this.mQueueToReject = queueToReject;
    }

    @Override
    public Boolean call() throws Exception 
    {
        while(true)
        {
            WorkUnit work = mQueueToReject.take();

            Socket socket = work.getSocket();

            // Code to reject the request.
        }
    }
}

-1voto

Jabir Points 1284

Vous devrez faire quelque chose comme ceci. ServiceThread est le fil qui va répondre aux demandes de service.

 while (true) {
              try {
                  Socket clientSocket = null;
                  if (null != serverSocket) {
                    clientSocket = serverSocket.accept();
                    ServiceThread serverThread = new ServiceThread(clientSocket); // Create a new thread for each client
                    serverThread.start();
                  }
              }  catch( Exception ex ) {
                  System.out.println("Exception while accepting connection " + ex.getMessage());
                  ex.printStackTrace();
              }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X