2009-05-24 4 views
0

Je veux écrire une programmation de socket java tcp en utilisant java NIO. Cela fonctionne bien. Mais j'utilise le même sélecteur pour accepter de lire et d'écrire aux clients.Comment puis-je créer différents sélecteurs pour accepter une nouvelle connexion dans Java NIO

Comment puis-je créer différents sélecteurs pour accepter une nouvelle connexion dans Java NIO, en lecture et en écriture. Y a-t-il de l'aide en ligne?

En fait, lorsque je suis occupé à lire ou à écrire, mon sélecteur utilise plus d'itérateur. Donc, si un plus grand nombre de clients est connecté, la performance de l'acceptation de la nouvelle coneection devient lente. Mais je ne veux pas que les clients acceptant soient lents

// Créer un sélecteur et enregistrer deux canaux socket Selector selector = null; try { // Créer le sélecteur selector = Selector.open();

// Create two non-blocking sockets. This method is implemented in 
    // e173 Creating a Non-Blocking Socket. 
    SocketChannel sChannel1 = createSocketChannel("hostname.com", 80); 
    SocketChannel sChannel2 = createSocketChannel("hostname.com", 80); 

    // Register the channel with selector, listening for all events 
    sChannel1.register(selector, sChannel1.validOps()); 
    sChannel2.register(selector, sChannel1.validOps()); 
} catch (IOException e) { 
} 

// Wait for events 
while (true) { 
    try { 
     // Wait for an event 
     selector.select(); 
    } catch (IOException e) { 
     // Handle error with selector 
     break; 
    } 

    // Get list of selection keys with pending events 
    Iterator it = selector.selectedKeys().iterator(); 

    // Process each key at a time 
    while (it.hasNext()) { 
     // Get the selection key 
     SelectionKey selKey = (SelectionKey)it.next(); 

     // Remove it from the list to indicate that it is being processed 
     it.remove(); 

     try { 
      processSelectionKey(selKey); 
     } catch (IOException e) { 
      // Handle error with channel and unregister 
      selKey.cancel(); 
     } 
    } 
} 

public void processSelectionKey(SelectionKey selKey) throws IOException { 
    // Since the ready operations are cumulative, 
    // need to check readiness for each operation 
    if (selKey.isValid() && selKey.isConnectable()) { 
     // Get channel with connection request 
     SocketChannel sChannel = (SocketChannel)selKey.channel(); 

     boolean success = sChannel.finishConnect(); 
     if (!success) { 
      // An error occurred; handle it 

      // Unregister the channel with this selector 
      selKey.cancel(); 
     } 
    } 
    if (selKey.isValid() && selKey.isReadable()) { 
     // Get channel with bytes to read 
     SocketChannel sChannel = (SocketChannel)selKey.channel(); 

     // See e174 Reading from a SocketChannel 
    } 
    if (selKey.isValid() && selKey.isWritable()) { 
     // Get channel that's ready for more bytes 
     SocketChannel sChannel = (SocketChannel)selKey.channel(); 
     } 
} 

Merci Deepak

+0

Les clients sont pré-acceptés par la pile TCP. Thats ce que la file d'attente de retard est pour. Les performances de ce dernier ne sont pas affectées par les performances de l'itérateur. Votre question semble plutôt inutile. Vous pouvez facilement augmenter l'arriéré, c'est tout ce dont vous avez besoin. – EJP

Répondre

0

Il y a beaucoup de online help.

Si vous voulez créer un nouveau sélecteur, allez-y et créez-en un autre (de la même manière que dans l'exemple de code que vous avez copié). Vous pouvez enregistrer des canaux avec seulement pour l'opération de connexion si vous le souhaitez (les docs couvrent cela, mais l'opération est OP_ACCEPT). Vous avez probablement besoin d'un pool de threads pour gérer le travail de traitement du client - de cette façon, votre thread principal peut mettre en file d'attente des éléments de travail et se remettre à accepter de nouvelles connexions sur le socket d'écoute tout de suite.

+0

Je n'ai pas pu créer –

+0

Eh bien, pourquoi ne pas coller le code que vous utilisez réellement, au lieu de l'exemple de code client? Si vous acceptez des connexions, vous devez utiliser un ServerSocketChannel quelque part. – JimG

0

Chaque sélecteur a besoin de son propre filetage.

Si vous voulez plusieurs sélecteurs, pourquoi ne pas simplement utiliser le blocage NIO, ce qui serait beaucoup plus simple. Les E/S non bloquantes n'ont de sens que si vous souhaitez que les connexions partagent des threads.

+0

Je ne vois rien qui puisse suggérer que deux sélecteurs ne puissent pas être utilisés sur le même fil. Cela semble fonctionner bien pour moi (bien que deux ne soit pas nécessaire pour n'importe quelle raison que je puisse penser). – JimG

+0

Vous pouvez utiliser n'importe quel nombre de sélecteurs dans un thread. Cependant, je ne vois pas le point, c'est-à-dire, qu'est-ce que cela vous donne qu'un seul sélecteur ne le ferait pas? –

+1

On dirait que nous sommes d'accord. C'était juste le libellé de "a besoin de son propre fil" qui me déroutait. Il serait possible d'avoir un seul sélecteur pour traiter les opérations d'acceptation, de sorte que vous pourriez donner la priorité à ces opérations de lecture/écriture. Je pense que c'est ce qu'il demande, même si cela n'a pas de sens et n'améliorera pas vraiment la performance comme il le souhaite sans travail supplémentaire. – JimG

Questions connexes