2009-08-13 6 views
2

J'ai du code Java qui effectue des requêtes via des sockets à partir d'un serveur écrit en C++. La communication est simplement que le code java écrit une ligne pour une requête et le serveur écrit alors une ligne en réponse, mais parfois il semble que le serveur ne répond pas, j'ai donc implémenté un timeout basé sur ExecutorService qui essaye de tomber et redémarrez la connexion.Comment faire pour supprimer/redémarrer une connexion client à un serveur de socket flaky

Pour travailler avec la connexion Je garde:

Socket server; 
PrintWriter out; 
BufferedReader in; 

réglage si la connexion est une question de:

server = new Socket(hostname, port); 
out = new PrintWriter(new OutputStreamWriter(server.getOutputStream())); 
in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

S'il n'y avait pas le code de délai d'attente de la demande/réception étapes sont tout simplement:

String request="some request"; 
out.println(request); 
out.flush(); 
String response = in.readLine(); 

Quand je reçu un délai d'attente que je tentais de fermer la connexion avec:

in.close(); 
out.close(); 
socket.close(); 

mais l'une de ces fermées semble bloquer et ne jamais revenir. Quelqu'un peut-il me donner une idée pourquoi l'un d'eux bloquerait et quelle serait la bonne façon d'abandonner la connexion et de ne pas se retrouver avec des problèmes de fuite de ressources?

Répondre

0

La fermeture du lecteur/enregistreur tamponné qui enveloppe le socket fermera le socket.
La fermeture d'une socket déjà fermée n'est pas correcte, mais cela ne devrait pas poser de problème. De toute façon, selon la prise java: Une fois qu'un socket a été fermé, il n'est pas disponible pour une utilisation ultérieure en réseau (c'est-à-dire qu'il ne peut pas être reconnecté ou rebondi). Une nouvelle socket doit être créée.

Vous devez donc créer un nouvel objet socket après avoir fermé celui-ci.

En ce qui concerne la gestion de la mémoire, le gestionnaire d'ordures doit éliminer l'ancien pour vous, ne vous inquiétez donc pas d'une fuite.

0

L'appel à out.close() peut bloquer car la méthode PrintWriter.close() est synchronisée sur le même verrou que la méthode println (String). Si l'appel original à println est bloqué en essayant d'écrire sur une mauvaise connexion, vous ne pourrez pas appeler close() dessus.

Avez-vous essayé d'utiliser la méthode Socket.setSoTimeout()?

+0

Je n'ai pas essayé d'appeler setSoTimeout(), cependant, il semble que cela n'affecte qu'un appel en lecture, si je suis bloqué dans l'appel en écriture (ce qui me semble être le fait que out.close() bloque également) ça ne m'aidera pas - correct? –

0

Je pense que vous avez seulement besoin de fermer le socket (et ensuite gérer les exceptions dans le thread de lecture/écriture en conséquence). En outre, comme indiqué ci-dessus, recréer le socket à partir de zéro.

Questions connexes