2013-05-01 5 views
0

Je dois appeler une méthode RMI pour transférer un fichier vers le serveur (exécution de la méthode RMI) forment le ClientProgrammation Socket et RMI Questions en liaison

Voici le code

RegisterMain: Le fichier java ayant la méthode RMI

Transfert: Classe client qui doit envoyer le fichier au serveur.

Test: La classe appelant les deux opérations.

public class RegisterMain extends UnicastRemoteObject implements RegMethod{ 


protected RegisterMain() throws RemoteException { 

    super(); 
    System.out.println("We're Connected"); 
} 

@Override 
public void FTransfer(String fname) throws RemoteException{ 

    try 
    { 
     String path="temp"+fname; 
     File f2=new File(path); 

     try { 

      Socket cli=new Socket("127.0.0.1",60000); 
      ObjectOutputStream outs = new ObjectOutputStream(cli.getOutputStream()); 
      ObjectInputStream ins = new ObjectInputStream(cli.getInputStream()); 
      FileWriter fw=new FileWriter(f2); 
      BufferedWriter bw=new BufferedWriter(fw); 


      int iter=(Integer) ins.readObject(); 
      System.out.println("Iterations :"+iter); 

      String str; 

      for(int i=0;i<iter;i++) 
      { 
       str=(String)ins.readObject(); 
       System.out.println(i); 
       fw.write(str); 
      } 

      str=(String)ins.readObject(); 
      fw.write(str); 

      outs.writeObject(new String("OverandOut")); 

      fw.close(); 
      bw.close(); 
      cli.close(); 


     } catch (Exception e) { 
      e.printStackTrace(); 
     } 


    } 
    catch(Exception e) 
    { 

    } 


} 

} 

Transfert:

public class Transfer extends Thread { 


String fname; 

public Transfer(String name) { 

    fname=name; 

} 

@Override 
public void run() { 

    super.run(); 

    try { 

     ServerSocket ser = new ServerSocket(60000); 
     Socket cli=ser.accept(); 

     ObjectOutputStream outs = new ObjectOutputStream(cli.getOutputStream()); 
     ObjectInputStream ins = new ObjectInputStream(cli.getInputStream()); 

     File f1=new File(fname); 
     FileReader fr=new FileReader(f1); 
     BufferedReader br=new BufferedReader(fr); 

     int flen=(int)f1.length(); 
     int iter=(int)flen/1024; 
     int latent=flen%1024; 
     System.out.println("Iterations :"+iter); 

     outs.writeObject(new Integer(iter)); 

     char[] buff=new char[1024]; 
     for(int i=0;i<iter;i++) 
     { 

      fr.read(buff, 0, 1024); 
      outs.writeObject(new String(buff, 0, 1024)); 
     } 

     fr.read(buff, 0, latent); 
     outs.writeObject(new String(buff, 0, latent)); 

     if(((String)ins.readObject()).equals("OverandOut")) 
     { 
      System.out.println("Terminating Connection."); 
     } 

     fr.close(); 
     br.close(); 
     ser.close(); 


    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

@Override 
public synchronized void start() { 

    super.start(); 
    run(); 

} 


} 

Test:

public class Test { 

public static void main(String[] args) throws UnknownHostException { 


    try 
    { 
     RegMethod intr=(RegMethod)Naming.lookup("//127.0.0.1/Register"); 

     Thread t1,t2,t3; 
     t1=new Transfer("Final.class"); 
     t1.start(); 
     intr.FTransfer("Final.class"); 

     t1=new Transfer("StatStore.class"); 
     t1.start(); 
     intr.FTransfer("StatStore.class"); 

     t1=new Transfer("Test.class"); 
     t1.start(); 
     intr.FTransfer("Test.class"); 


    }catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 

} 

} 

J'utilise RMI pour invoquer une méthode sur le même système (localhost) (J'utilise ceci sur Ubuntu). Dans ma logique de programme dans la méthode distante, je crée un Socket et dans un autre Thread je crée un ServerSocket. et je cours le fil avant que je puisse donner l'appel à la procédure à distance.

maintenant j'ai essayé de lancer mon programme en utilisant divers ports, mais il me jette toujours une exception

java.net.SocketException: Address already in use 
    at java.net.PlainSocketImpl.socketListen(Native Method) 
    at java.net.AbstractPlainSocketImpl.listen(AbstractPlainSocketImpl.java:365) 
    at java.net.ServerSocket.bind(ServerSocket.java:337) 
    at java.net.ServerSocket.<init>(ServerSocket.java:202) 
    at java.net.ServerSocket.<init>(ServerSocket.java:114) 
    at Transfer.run(Transfer.java:39) 
    at Transfer.start(Transfer.java:87) 
    at Test.main(Test.java:24) 

Je courais tous les modules sur la même machine (par exemple localhost)

Dans un stand seule classe, la même logique fonctionne sans aucune erreur. Ma question est que c'est à cause de RMI et Sockets à la fois que mon programme lance une telle exception ?? Si oui, comment pourrais-je résoudre le problème?

+0

N'est-ce pas le problème de sam comme ici: http://stackoverflow.com/questions/8337215/remote-method-invocation-port-in-use –

+0

Ce code ne jette pas cette exception. Le code appelle lookup(): l'exception provient de bind(). Veuillez poster le code * pertinent *. Je ne sais pas pourquoi vous créez des Sockets et des ServerSockets lorsque vous utilisez déjà RMI mais cela ne semble pas pertinent. – EJP

+0

J'ai besoin de transférer un fichier sur le serveur et je le fais par l'utilisation de sockets. C'est la seule raison précise pour utiliser RMI et les sockets – Abhishek

Répondre

0

Le serveur ServerSocket se plaint qu'il ne peut pas se lier au port 60000 car il est déjà utilisé. Soit vous n'avez pas fermé le précédent ou quelque chose d'autre l'utilise. Vous devez le fermer dans un bloc finally; votre code actuel provoquera ce problème s'il existe une exception.

Rien à voir avec RMI, sauf que cette implémentation ne peut être utilisée que par un client à la fois. Peut-être que vous devriez créer le ServerSocket sur le port 0 et renvoyer son numéro de port local au client à la suite de l'appel de méthode qui le crée, et le faire servir dans un thread séparé. Ou peut-être qu'il devrait être créé une fois au lieu de par appel.