PB socket java.nio.channels.Selector
Bonjour,
Je suis actuellement en cours de dev d'un serveur de socket.
Il fonctionne très bien. Son mode de fonctionnement est le suivant (résumé).
Un objet selector est notifié des évènements (clients) sur le socket d'écoute du serveur (ACCEPT,CONNECT,READ,WRITE). Tant que l'évènement n'est pas traité le selector ne passe pas a un autre.
Lors d'une tentative de connexion un évènement ACCEPT est d'abord généré. Avant de finaliser la connexion, je regarde si le nombre maximum de client est atteins si oui je refuse la connexion si non je valide la connexion par un .accept du socket.
Mon problème est que je n'arrive pas à refuser la tentative de connexion. En effet, l'évènement ACCEPT reviendra tant que je ne l'aurais pas traité. Comment faire?
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
/**
* Fonction principale du thread.
*
* <p>Boucle sans fin qui reçoit les évènements du selectorThread</p>
*/
public void run() {
while (!closeRequested) {
//Exécution des taches
doInvocations();
//Requête de fermeture du thread
if (!closeRequested) {
int selectedKeys;
try {
selectedKeys = selector.select();
} catch (IOException ioe) {
listenerError.eventError(ioe);
continue;
}
if (selectedKeys == 0) {
/*si réveillé par 'selector.wakeup()'
et pas d'évènement à traiter*/
continue;
}
// Récupère la liste des events
final Iterator < SelectionKey > itSKey = selector.selectedKeys()
.iterator();
while (itSKey.hasNext()) {
final SelectionKey sKey = (SelectionKey) itSKey.next();
itSKey.remove();
eventDistribution(sKey);
}
}
}
if (closeRequested) {
//fermeture
try {
closeSelectorAndChannels();
} catch (IOException ex) {
listenerError.eventError(ex);
}
}
}
/**
* Fonction permettant de répartir les évènements vers les interfaces.
*
* @param sKey Descripteur de l'evènement
*/
private void eventDistribution(final SelectionKey sKey) {
try {
final int readyOps = sKey.readyOps();
//disable l'évènement
sKey.interestOps(sKey.interestOps() & ~readyOps);
if (sKey.isAcceptable()) {
//Évènement ACCEPT
if (currentAccept >= MAX_ACCEPT) {
//!!!! signale juste le refus mais ne fais rien
((ISelectorListenerAccept) sKey.attachment()).eventRefused();
} else {
//!!!!! accept la connexion par .accept()
((ISelectorListenerAccept) sKey.attachment()).eventAccept();
}
} else if (sKey.isConnectable()) {
//Évènement CONNECT
((ISelectorListenerConnect) sKey.attachment())
.eventConnect();
} else {
if (sKey.isReadable()) {
//Évènement READ
((ISelectorListenerReadWrite) sKey.attachment())
.eventRead();
}
if (sKey.isValid() && sKey.isWritable()) {
//Évènement WRITE
((ISelectorListenerReadWrite) sKey.attachment())
.eventWrite();
}
}
} catch (CancelledKeyException ex) {
//Fermeture des connexions
try {
closeSelectorAndChannels();
listenerError.eventError(ex);
} catch (IOException exClose) {
//+ Erreur à la fermeture
exClose.initCause(ex);
listenerError.eventError(exClose);
}
}catch (NullPointerException ex) {
//Fermeture des connexions
try {
closeSelectorAndChannels();
listenerError.eventError(ex);
} catch (IOException exClose) {
//+ Erreur à la fermeture
exClose.initCause(ex);
listenerError.eventError(exClose);
}
}
} |