2016-03-17 1 views
2

J'essaye de créer et de maintenir une connexion TCP à un hôte à partir d'une application Java autonome.Connexion réinitialisée par un homologue: erreur d'écriture du socket. Quel est le problème avec mon code Java

Le port local et le port du serveur sont identiques = 8999. Après la connexion, je dois envoyer un message au serveur: <STX>username=fred&password=abcd<ETX>.

Le code pour la création de socket et envoi de message va comme:

Socket socket = new Socket("mshxml.abcd.com", 8999, InetAddress.getLocalHost(), 8999); 
OutputStream outStream = socket.getOutputStream(); 
while (socket.isConnected()) { 
    try { 
     int stx = 2, etx = 3; 
     DataOutputStream dout = new DataOutputStream(outStream); 
     dout.writeByte(stx); 
     dout.writeBytes("username=fred&password=abcd"); 
     dout.writeByte(etx); 
    } catch (Exception e) { 
     e.printStackTrace(); 
} 

Mais la connexion ne persiste pas. Le débogage, je trouve l'erreur suivante:

java.net.SocketException: Connection reset by peer: socket write error 
     at java.net.SocketOutputStream.socketWrite0(Native Method) 
     at java.net.SocketOutputStream.socketWrite(Unknown Source) 
     at java.net.SocketOutputStream.write(Unknown Source) 
     at java.io.DataOutputStream.writeBytes(Unknown Source) 
     at com.voya.socketprog.CClient.createConnection(CClient.java:120) 
     at com.voya.socketprog.CClient.createSocket(CClient.java:33) 
     at com.voya.socketprog.CClient.main(CClient.java:138) Line 120 is: dout.writeBytes("username=fred&password=abcd"); 

Note: Ce même programme fonctionne avec succès lorsque vous êtes connecté à un serveur factice (localhost) sur ma machine où je suis capable de recevoir et d'envoyer des messages.

Aidez-nous s'il vous plaît.

+0

'Le port local et le port du serveur sont identiques = 8999' Pourquoi? – EJP

Répondre

0
while (socket.isConnected()) { 

Le problème est ici.

  1. Il n'y a aucune raison pour que la boucle while en premier lieu. C'est un message de connexion: il ne doit être envoyé qu'une seule fois. Le serveur n'attend certainement pas un second d'une connexion connectée, donc il se ferme.

  2. isConnected() n'est pas un test valide pour la connexion toujours présente. Le seul test valide est l'absence d'un IOException tel que celui que vous obtenez, ce qui signifie que l'homologue a fermé la connexion. Et quand vous obtenez une telle exception, tout ce que vous pouvez faire est de fermer la prise et d'arrêter d'essayer. Réessayer est inutile: la connexion a disparu.

Socket.isConnected() ne vous dit sur l'état de la Socket. Pas de la connexion. Vous avez connecté cette prise, donc c'est connecté. NB: Vous devez utiliser les mêmes flux pour la durée de vie du socket, et ne pas en créer un nouveau par message.

+0

J'ai supprimé les lignes 'while' et 'Socket.isConnected()'. Je suis toujours confronté à la même erreur sur la ligne 'dout.writeBytes ("username = fred & password = abcd");' . Fondamentalement, je suis confronté à cette erreur chaque fois que j'essaye d'écrire la 2ème fois dans le 'dataoutputstream'. (Si je supprime cette ligne particulière, l'erreur viendra dans la ligne suivante, c'est-à-direquand j'écris ETX) @EJP – Pratap

+0

Si c'est vraiment vrai, votre idée du protocole d'application est fausse. Le pair ne reconnaît même pas le STX. Mais je trouve cela très difficile à croire. Il n'y a pas assez de temps entre l'envoi du STX et la deuxième ligne pour que le pair ait reçu le STX et fermé le socket, et que votre hôte ait reçu le close, avant d'envoyer la deuxième ligne. Est-ce que vous envoyez quelque chose d'autre invalide à l'avance? – EJP

-1

@EJP @weston Le problème a été résolu après beaucoup d'essais &. Le code de travail est la suivante:

Socket socket = new Socket("mshxml.abcd.com", 8999, InetAddress.getLocalHost(), 8999); 
OutputStream outStream = socket.getOutputStream(); 

    try { 
    String STX = new Character((char) 2).toString(); 
    String ETX = new Character((char) 3).toString(); 
    OutputStreamWriter osw = new OutputStreamWriter(outStream); 
    BufferedWriter bw = new BufferedWriter(osw); 

    bw.write(STX + "username=fred&password=abcd" + ETX); 
    bw.flush(); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

Mais je n'ai aucune idée pourquoi ce code fonctionne et l'original ne l'était pas. Toutes les suggestions seraient très appréciées. Et merci beaucoup d'avoir supporté mes requêtes et mes publications en double. :)

@EJP concernant votre pensée sur le serveur de fermeture de la connexion entre la réception de STX et la ligne suivante, vous avez raison. Le serveur n'a pas fermé la connexion tout de suite; Ce n'est que pendant le débogage (lorsque le serveur a eu le temps d'analyser les octets) que j'ai remarqué qu'il le faisait.

+0

Ce code ne fonctionne pas. Vous ne me convaincrez pas que le serveur attend un nombre infini de chaînes de connexion, et le test 'isConnected()' reste invalide. Vous avez changé quelque chose d'autre. – EJP

+0

alors que la déclaration a été ajoutée par erreur ici. Mise à jour le code. – Pratap

+0

Et maintenant vous ne me convaincrez pas que le code 'DataOutputStream' de votre version originale ne fonctionnait pas une fois que vous avez supprimé la boucle. Les 'writers' ne sont pas pour les données binaires. – EJP