2011-09-11 5 views
-1

J'ai écrit un client de chat qui fonctionnait bien jusqu'à ce que je décide d'ajouter quelque chose d'expéditeur de fichier qui devrait envoyer un fichier du client au serveur. Après avoir ajouté les lignes pour l'expéditeur du fichier, il ne montre plus les messages.Problèmes d'écriture de chat Java

Je pense que le problème est ici, avec deux instructions try dans run().

public void run(){ 

    InputStream input = null; 

    try{ 
     input = socket.getInputStream(); 
     BufferedReader inReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     BufferedWriter outReader = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 

     //Citeste calea fisierului 
     String filename = inReader.readLine(); 
     if(filename.equals("")){ 
      //Trimit status READY la client 
      outReader.write("READY\n"); 
      outReader.flush(); 
     } 

     FileOutputStream wr = new FileOutputStream(new File("C://tmp/"+filename)); 
     byte[] buffer = new byte[socket.getReceiveBufferSize()]; 
     int bytesReceived = 0; 
     while((bytesReceived = input.read(buffer)) > 0){ 
      wr.write(buffer,0,bytesReceived); 
     } 

    } 

    catch(IOException e){ 
     Logger.getLogger(ConectareClient.class.getName()).log(Level.SEVERE,null,e); 
    } 

    try{ 
     //Inregistreaza firul curent in listaObiecte 
     listaObiecte.addElement(this); 

     System.out.println("\n Fir de executie nou"); 
     System.out.println(this.toString()); 
     System.out.println(listaObiecte.toString()); 

     //Bucla 
     while(true){ 
      //Se citeste mesajul din fluxul de intrare trimis de client 
      String mesaj = fluxIntrare.readUTF(); 
      //Se transmite mesajul catre toti clientii conectati 
      transmite(mesaj); 
     } 
    } 
    //Tratare exceptie conexiune 
    catch (IOException e){ 
     e.printStackTrace(); 
    } 
    finally{ 
     //Stergere fir curent din listaObiecte 
     listaObiecte.removeElement(this); 

     System.out.println("\n Fir de executie inchis"); 
     System.out.println(this.toString()); 
     System.out.println(listaObiecte.toString()); 

     try{ 
      //Inchidere socket 
      socket.close(); 
      input.close(); 
     } 
     //Tratare exceptie conexiune 
     catch (IOException e){ 
      e.printStackTrace(); 
     }  
    } 
} 

    private static void transmite(String mesaj){ 
    //Enumerare generata de lista firelor de executie 
    Enumeration enm = listaObiecte.elements(); 

    //Cat timp mai sunt elemente in enumerare 
    while(enm.hasMoreElements()){ 
     //Se initializeaza cu null referinta firului curent 
     ConectareClient firDestinatie = null; 

     //Se protejeaza vectorul firelor de acces simultan 
     synchronized(listaObiecte){ 
      //Se memoreaza referinta catre firul curent 
      firDestinatie = (ConectareClient) enm.nextElement(); 
     } 
    //Referinta valida 
     if(firDestinatie != null){ 
      try{ 
       //Se protejeaza fluxul de iesire de acces simultan 
       synchronized(firDestinatie.fluxIesire){ 
        //Scriere mesaj in flux de iesire 
        firDestinatie.fluxIesire.writeUTF(mesaj); 
       } 
       //Mesajul este transmis 
       firDestinatie.fluxIesire.flush(); 
      } 
      catch(IOException e){ 
       firDestinatie.stop(); 
      } 
     } 
    }  
} 

Ici vous pouvez télécharger tous les fichiers source. http://www.megaupload.com/?d=ULFDBP6M

Merci.

+0

Le client peut-il envoyer un fichier appelé «.. \ windows \ system32 \ user32.dll»? –

+0

bien, la partie d'envoi de fichier a été prise à partir d'une autre application que j'ai écrite et il fonctionnait très bien, envoyant tous les types de fichiers. –

+0

Oui, c'est exactement le problème que j'ai essayé de vous dire. Lorsque le client envoie un nom de fichier contenant '..', le serveur écrase complètement les fichiers non liés, ce qui ne devrait pas être le cas. Vous devez vérifier les * mauvais noms de fichiers * avant de créer le fichier. –

Répondre

0

Il semble qu'il y ait une petite erreur de logique dans ConnectareClient.java. La condition pour envoyer "READY", je crois devrait être une condition NON, sinon il n'enverrait jamais cette réponse au client et procéder à l'écriture du fichier. Je l'ai déjà essayé et j'ai pu voir que le fichier était copié du client vers le serveur.

est en dessous du changement de code que je l'ai fait dans ConnectareClient.java


//Citeste calea fisierului 
String filename = inReader.readLine(); 

// this seems should be a NOT condition 
if(!filename.equals("")){ 
    //Trimit status READY la client 
    outReader.write("READY\n"); 
    outReader.flush(); 
} 
+0

ne fonctionne toujours pas –

+0

Quelle est l'erreur? La seule autre chose que je change est de faire le point c:/temp à mon répertoire temporaire dans Mac. Vous devez être plus précis si vous voulez que nous vous aidions au lieu de dire que cela ne fonctionne pas – momo

+1

Vérifiez si votre client reçoit le message READY du serveur après la modification. – momo

1

J'ai téléchargé et essayé votre code. En bref, votre problème est l'interblocage des threads. Vous avez deux threads, l'un côté serveur et l'autre côté client, chacun attendant que l'autre fasse quelque chose pour que le premier thread puisse continuer.

En plus de détails, voici ce qui se passe:

  • la classe ClientChat envoie le nom du fichier sur le serveur à la ligne 260, puis attend que le serveur d'envoyer quelque chose (une chaîne avec « READY ») d'autre part, la classe ConectareClient s'arrête à la ligne 38 et attend que quelque chose soit envoyé par le client avant de continuer (et envoie le message d'état "READY", qui à son tour le client attend).

Mon conseil pour vous est la suivante:

Cela ressemble beaucoup à un devoir asignement que certains professeur poussiéreux vous a donné :) Et il semble que le gars a donné cela pour vous sans passer d'abord par les bases du développement logiciel. Je ne vais pas editorialise ici, mais voici quelques conseils pratiques qui pourraient vous aider:

  • utiliser un IDE tel que Eclipse. N'écrivez pas de code dans la ligne de commande en utilisant le bloc-notes. Dans ce cas, Eclipse vous bénéficierait énormément simplement de la facilité avec laquelle vous pourriez déboguer votre code pour sauvegarder ces erreurs triviales. Voici ce que vous devez faire: Téléchargez Eclipse, créez un projet standard Java, copiez tous vos fichiers .java et collez-les dans le dossier "src" du projet Eclipse. Puis ajoutez quelques points de rupture aux lignes que je mentionne ci-dessus, démarrez à la fois le client et le serveur, essayez d'envoyer un fichier et voyez ce qui se passe dans votre code.

  • Faites des tests unitaires! C'est très important, peu importe ce que votre professeur et vos collègues pourraient dire. Faire des tests unitaires aura un double avantage sur votre codage: 1. Il vous aidera à repérer facilement ces erreurs de régression de refactorisation. 2. il vous forcera à écrire du bon code propre, avec des méthodes individuelles pour chaque tâche etc.Bien que la connaissance des threads et sockets de bas niveau du serveur/client ne soit pas mauvaise, un meilleur moyen d'atteindre ce que vous essayez de faire dans ce projet est d'utiliser Java Messenger Service. C'est un framework qui fait exactement ce que vous voulez, à savoir envoyer et recevoir toutes sortes de choses (primitives, objets etc) de manière synchrone ou asynchrone et tout l'échafaudage est déjà fait pour vous, il suffit de mettre en œuvre la logique métier. Regardez-le, cela pourrait vous aider beaucoup.

+0

merci pour les conseils, je vais essayer de supprimer l'attente pour READY partie et voir ce qui se passe –