Comme pour UDP, un serveur doit écouter sur un port particulier (sur lequel les clients le solliciteront).
Contrairement à UDP, il faut que le serveur "accepte" la connexion d'un client avant de pouvoir en recevoir les données.
Donc, pour traiter un client, il faut :
Le serveur survit à la fermeture de la connexion du client.
La ServerSocketChannel
.
// create the server socket var serverSocketChannel = ServerSocketChannel.open(); // and bind it to its listening port serverSocketChannel.bind(new InetSocketAddress(port));
La ServerSocketChannel
est la porte d'entrée du serveur. C'est là que les clients viennent "frapper" pour établir une connexion.
L'attente d'une connexion cliente par accept
est
bloquante par défaut : un client est accepté quand la méthode retourne.
Ce client est représenté par une SocketChannel
qui s'utilise
de manière symétrique sur le serveur et sur le client.
while (...) { // waiting for incoming client connection SocketChannel client = ssc.accept(); // Serve the client... // then close its connexion this client client.close(); }
On peut fermer (définitivement) la socket serveur par l'appel à la méthode ssc.close()
.
Attention : si la communication avec un client lève une exception qui n'est pas capturée... elle "tue" le serveur !
while(!Thread.interrupted()) { SocketChannel client = serverSocketChannel.accept(); try { logger.info("Connection accepted from " + client.getRemoteAddress()); serve(client); } catch (IOException ioe) { logger.log(Level.INFO,"Connection terminated by IOException ", ioe.getCause()); } catch (InterruptedException ie) { logger.info("Server interrupted"); break; } finally { silentlyClose(client); } }Si l'appel à
accept()
lève une Exception
, celle-ci est propagée.
Pendant que le serveur s'occupe d'un premier client, il ne cherche pas à en accepter un deuxième.
Mais, si un autre client tente de se connecter, le système d'exploitation peut l'accepter, cependant il ne sera pas pris en compte par l'application.
On parle de connexion pendante.
Elle sera prise en compte par le prochain appel à accept()
.
Le nombre de connexions pendantes est borné par le système : au delà, il refuse d'en accepter de nouvelles.
Pour traiter plusieurs clients simultanément, on peut utiliser plusieurs threads.
Dans l'absolu, il faut :
Au delà d'un certain nombre de clients, ce n'est pas raisonnable !