hello,
j'ai bien dû galérer une heure sur une broutille à propos d'un serveur TCP codé en Java.
Le problème: j'ai voulu réutiliser un code autour d'un ServerSocket (pour l'écoute sur un port TCP, donc) qui marchait parfaitement depuis des lustres.
Le code ressemblant à ceci:
Le code du 'nouveau' serveur fonctionnait parfaitement sous Windows Seven, et les clients pouvaient se connecter sans souci. Mais dès que je testais le même code sur sous Debian, rien à faire: impossible aux clients d'établir une connexion en 127.0.0.1: la connexion était systématiquement refusée.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 // ... ServerSocket listener = new ServerSocket(monPortAEcouter); Socket client = listener.accept(); // ...
J'ai finalement trouvé l'origine du problème et la solution: la socket serveur n'écoutait en fait que sur l'interface IPv6 (et pas IPv4) et donc un 'telnet 127.0.0.1 monPort' était réfusé alors qu'un 'telnet ::1 monPort' marchait parfaitement. La raison: sur les distributions Debian squeeze et postérieures, un paramètre 'bindv6only' est activé par défaut (ie. mis à 1). Editer le fichier '/etc/sysctl.d/bindv6only.conf' et y mettre la valeur '0' résout le souci.
Voilà pour la (trop) longue introduction.
Mais cela m'amène à deux questions:
- je pensais naïvement que Serversocket(int port) écoutait par défaut sur toutes les interfaces réseaux et tous les protocoles (IPv4 et IPv6), ce qui n'est visiblement pas le cas. Mais dans ce cas, comment fait Java pour choisir arbitrairement un protocole et/ou une interface plus qu'une autre ?
- y a-t-il un moyen simple pour faire une ServerSocket qui écoute sur toutes les interfaces d'une version d'IP donnée, sans passer par une itération 'manuelle' sur chaque interface comme le propose la FAQ ?
Merci d'avance
Partager