NIO client donnant exception : java.net.ConnectException: Connexion refusée: pas d'autres informations
J'ai modifié l'exemple de code disponible ici pour le Client et le Serveur
Mon client :
public class Client {
public static void main(String[] args) {
int n=10000;
SocketTest [] st= new SocketTest[n];
for(int i=0;i<n;i++)
st[i]= new SocketTest("hi");
for(int i=0;i<n;i++)
new Thread(st[i]).start();
}
}
class SocketTest implements Runnable {
private String message = "";
private Selector selector;
private int i;
public SocketTest(String message){
this.message = message;
}
@Override
public void run() {
SocketChannel channel;
try {
selector = Selector.open();
channel = SocketChannel.open();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_CONNECT);
channel.connect(new InetSocketAddress("127.0.0.1", 8511));
while (!Thread.currentThread().isInterrupted()){
selector.select();
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while (keys.hasNext()){
SelectionKey key = keys.next();
keys.remove();
if (!key.isValid()) continue;
if (key.isConnectable()){
connect(key);
System.out.println("I am connected to the server");
}
if (key.isWritable()){
write(key);
}
if (key.isReadable()){
read(key);
}
}
}
} catch (IOException e1) {
//TODO Auto-generated catch block
e1.printStackTrace();
} finally {
close();
}
}
private void close(){
try {
selector.close();
} catch (IOException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
private void read (SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer readBuffer = ByteBuffer.allocate(1000);
readBuffer.clear();
int length;
try{
length = channel.read(readBuffer);
} catch (IOException e){
System.out.println("Reading problem, closing connection");
key.cancel();
channel.close();
return;
}
if (length == -1){
System.out.println("Nothing was read from server");
channel.close();
key.cancel();
return;
}
readBuffer.flip();
byte[] buff = new byte[1024];
readBuffer.get(buff, 0, length);
//length=buff.length;
String fromserver = new String(buff,0,length,"UTF-8");
length = fromserver.length();
System.out.println("Server said: "+fromserver);
key.interestOps(SelectionKey.OP_WRITE);
}
private void write(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
i++;
message = "location now "+i;
try{
Thread.sleep(5000);
}
catch(InterruptedException ie)
{
System.out.println(""+ie);
}
channel.write(ByteBuffer.wrap(message.getBytes()));
//lets get ready to read.
key.interestOps(SelectionKey.OP_READ);
}
private void connect(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
try
{
if(!channel.finishConnect())
System.out.println("* Here *");
}
catch(ConnectException e)
{
System.out.println("BP 1");
e.printStackTrace();
//channel.close();
//key.cancel();
//return;
}
/*if (channel.isConnectionPending()){
while(!channel.ffinishConnect()){
System.out.println("not connected");
}
}*/
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_WRITE);
}
}
- Je créer plusieurs clients sur la même machine par la création de plusieurs threads.
Pas de threads sont déterminés par la valeur de n.
Quand je lance des petits pas de clients, je rencontre pas de problème mais dès que je lance avec n 500, c'est à dire 500 clients threads , certains threads s'exécutent correctement, mais dans certains, je rencontre ce :
java.net.ConnectException: Connection refused: no further information
at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
at sun.nio.ch.SocketChannelImpl.finishConnect(Unknown Source)
at SocketTest.connect(Client.java:143)
at SocketTest.run(Client.java:61)
Ligne 143 est :
if(!channel.finishConnect())
Donc quand j'ai lu la documentation de cette méthode qu'il dit qu'il en jette :
NoConnectionPendingException - Si ce canal n'est pas connecté et une opération de raccordement n'a pas été initiée.
ClosedChannelException - Si ce canal est fermé.
AsynchronousCloseException - Si un autre thread ferme cette chaîne alors que l'opération de connexion est en cours.
ClosedByInterruptException - Si un autre thread interrompt le thread en cours alors que l'opération de connexion est en cours, fermant ainsi le canal et le réglage de la thread en cours d'interruption du statut.
IOException - Si une autre erreur d'e/S se produit.
Mais l'Exception est ConnectException.
J'ai essayé de l'attraper mais il n'est pas aller dans le bloc catch.
Toute aide sera appréciée. Merci.
EDIT :
Je travaille sur windows.
J'ai essayé de changer la valeur de n voir combien de clients ont été créés et combien causé des exceptions et ce sont les résultats(je sais que l'attente pour plus de temps après chaque test permettra pour plus d'ouvrir des sockets comme après chaque test scokets sera publié après TIME_WAIT ) :
n clients connected(by keeping a count at server)
1000 522
2000 568
3000 626
4000 600 (maybe I gave less time before successive runs)
5000 1345
6000 1389
Je suis problemed par la façon dont peut seulement ces nombreux clients de se connecter.
Quelqu'un peut s'il vous plaît suggérer de meilleures références à lire pour le Client-Serveur NIO.
EDIT 2
Comme EJP mentionné dans son commentaire, le Carnet de commandes de la fenêtre de File d'attente était pleine.
J'ai modifié le code Client pour générer 100 threads et puis dormir pendant 5 secondes et de cette façon il n'y avait pas beaucoup de charge sur la File d'attente et plus de la connexion ont été couronnées de succès(mais toujours lors de la prise de 10 000 connexions certains ont toujours échoué).
Je suis avec windows
OriginalL'auteur cruxion effux | 2015-05-27
Vous devez vous connecter pour publier un commentaire.
ConnectException: connection refused
signifie rien n'a été à l'écoute à l'adresse IP:port que vous avez essayé de vous connecter, ou sur certaines plates-formes que le serveur écoute de l'arriéré de la file d'attente pleine. Si elle est générée et vous l'attraper correctement, vous aurez certainement l'attraper. Vous devez étendre sur ce qui se passe réellement et ce que vos prises réelles à quoi ressemble le code pour obtenir de l'aide.Cependant, vous avez beaucoup d'autres problèmes:
À ce point, si
finishConnect()
retourné false, vous devez retourner. Vous devriez pas tomber à travers et de ré-enregistrer le canal pourOP_WRITE.
La connexion est toujours en attente. L'impression"* Here *"
est également assez futile. Essayez d'imprimer quelque chose de significatif.Vous devriez certainement fermer le canal à ce point. C'est de ne plus l'utiliser à l'homme ou de la bête.
La fermeture du canal annule la clé. Retirez où rencontrés.
Comme ci-dessus, vous devriez certainement revenir à ce point.
Se débarrasser de cette crasse. Il n'est jamais approprié de tourner en boucle en mode sans blocage. Ne même pas laisser traîner comme des commentaires: un idiot peut venir plus tard et de jouer avec de le remettre.
Le canal est déjà en mode sans blocage. Sinon vous ne seriez pas ici. Retirez.
Une autre façon de le faire est
key.interestOps(SelectionKey.OP_WRITE);
De couchage dans le code réseau est littéralement une perte de temps. Il ne résout rien.
Vous êtes en supposant que
write()
réussi complètement, et vous êtes ignorant le comte il retourne.Vous utilisez une assez mauvaise qualité référence:
write()
appliquer comme ci-dessus.flip()
n'est pas "comme un reset".ByteBuffer,
mais en tout cas, l'allocation d'uneByteBuffer
par lire est une mauvaise pratique.ServerSocketChannel.accept()
pouvez retournernull.
Map
lorsque les clés des pièces jointes.Thread.interrupted()
quand NIO est interruptible de toute façon.IOException
sur un seul canal.Essayer de trouver quelque chose de mieux.
L'écoute de la file d'attente peut se remplir si votre serveur n'accepte pas les connexions aussi vite qu'ils viennent. Cela sonne comme le problème: lors de l'une des Fenêtres de l'arriéré de la file d'attente est pleine, elle commence à refuser les connexions.
1)Pouvez-vous nous dire ce qui est le plus commun de la taille de la file d'attente en retard.J'ai lu il est de 5 pour les non serveur Windows de la machine et 200 pour les machines serveur.Suis-je la corriger ? 2)j'ai mis thread de sommeil lors de la prise de nouveaux clients.e 100 des clients, puis 5 secondes de sommeil et de 100 clients. Il fonctionne bien, pour environ 4000 threads.Mais quand je créer 10 000 threads , 8500 ou alors survécu. Pour le reste de connexion a été refusée. Pouvez-vous dire ce que peut être la raison ? Je pense que l'arriéré de la file d'attente ne peut pas être la raison d'abord, il manipulé ?
50 ou par défaut du système. (2) Lorsque vous mettez le nombre de personnes dans le carnet de commandes de la file d'attente ne soit pas trop loin de votre accepter la boucle. Lorsque vous avez pris, vous acceptez boucle ne pouvait pas suivre, de sorte que le carnet de commandes de la file d'attente pleine. Voir si vous pouvez accélérer votre accepter la boucle: par exemple, déplacer le fil d'initialisation dans le
run()
méthode.OriginalL'auteur user207421
Je crois que le
ConnectException
que vous obtenez avec 500 threads ne vient pas deSocketTest.connect()
. Il pourrait être à venir à partir de l'un quelconque des autres IO méthodes.Pour une solution rapide (et pour vous en convaincre), vous pouvez explicitement attraper
ConnectException
dans votre principaletry-catch
bloc comme ceci:Pourquoi ce qui se passe, je peux vous dire que je suis actuellement en augmentant jusqu'à des centaines de threads pour le test d'un service SOAP. Je reçois aussi des pertes de connexion tous sur la place, c'est peut-être à attendre avec un tel grand nombre de threads simultanés.
SocketChannel.finishConnect().
OriginalL'auteur Tim Biegeleisen