2016-04-24 1 views
0

Je vais essayer d'être bref.Comment recevoir IP publique et Port en utilisant Stun et ice4j

Je souhaite créer une communication entre 2 applications Java (qui seront ensuite transportées vers Android) sans passer par un serveur. En tant que tel, j'ai passé des semaines à regarder autour, et après beaucoup de travail, j'ai trouvé étourdissement et ice4j. La meilleure explication sur l'utilisation de ice4j, j'ai trouvé here, et cela m'a montré ce que je devais faire pour ajouter des serveurs d'étourdissement à un agent (je ne sais pas vraiment ce qu'est un agent, juste qu'il gère mes communications avec STUN et TURN), à travers ce code:

import java.io.IOException; 
import java.net.InetAddress; 
import java.net.UnknownHostException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import org.ice4j.Transport; 
import org.ice4j.TransportAddress; 
import org.ice4j.ice.Agent; 
import org.ice4j.ice.IceMediaStream; 
import org.ice4j.ice.harvest.StunCandidateHarvester; 

public class ice4jTesting { 

    public static void main(String[] args) { 

     Agent agent = new Agent(); 
     String[] hostnames = new String[] {"jitsi.org", "numb.viagenie.ca", "stun.ekiga.net"}; 

     for(String hostname: hostnames) { 
      try { 
       TransportAddress address; 

       address = new TransportAddress(InetAddress.getByName(hostname), 3478, Transport.UDP); 
       agent.addCandidateHarvester(new StunCandidateHarvester(address)); 
      } catch (UnknownHostException ex) { 
       Logger.getLogger(SimpleStun.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 

     IceMediaStream stream = agent.createMediaStream("audio"); 
     int port = 5000; 
     try { 
      agent.createComponent(stream, Transport.UDP, port, port, port+100); 
      // The three last arguments are: preferredPort, minPort, maxPort 
     } catch (IllegalArgumentException | IOException ex) { 
      Logger.getLogger(SimpleStun.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

cependant, après le tutoriel utilise SDPUtils, une classe qui est dans le code source de ice4j j'ai trouvé sur github, pour recevoir les informations SDP de l'agent. Cependant j'ai obtenu ice4j.jar de the central maven repository, et l'ai ajouté à mon projet régulier de netbeans (je l'ai fait parce que je ne suis pas très familier avec le maven, et je voulais juste une bibliothèque régulière sur mon projet régulier). Cette classe n'a pas la classe SDPUtils, et comme je ne comprends pas assez ce code pour le résoudre moi-même, je me demandais si vous pouviez m'aider soit à corriger le code ci-dessus, soit à me montrer un exemple de comment pour répondre à la question sur le titre. Cependant, à moins que vous ne puissiez faire ce que j'ai dit dans la dernière phrase, ou que vous m'indiquiez un exemple de code, votre aide ne sera probablement pas utile, car je suis mentalement incapable de comprendre la théorie derrière cela complètement à cause de les nombreux concepts que je ne connais pas.

J'ai jusqu'à la fin de cette semaine pour comprendre cela, et si je ne le fais pas, je suis assez foutu. Alors s'il vous plaît, si vous pouvez ou connaissez quelqu'un qui peut vous aider, je l'apprécierais énormément.

Merci d'avoir lu jusqu'à présent et essayer d'aider :)

+0

Merci pour le réalisation de tumbleweed les gars ... – RaKXeR

Répondre

4

Il vous allez
SdpUtils.java

En fait, je travaille aussi sur le même que mon projet de l'Université. De la semaine dernière, je creuse web pour la connexion p2p établir sur nat.
Je sais que la forme où vous avez ci-dessus code snipet, je voudrais vous informer qu'il ya des erreurs dans ce code est ici celui que je corrigeais

import java.io.IOException; 
import java.net.BindException; 
import java.net.InetAddress; 
import org.ice4j.Transport; 
import org.ice4j.TransportAddress; 
import org.ice4j.ice.Agent; 
import org.ice4j.ice.IceMediaStream; 
import org.ice4j.ice.harvest.StunCandidateHarvester; 

public class IceTest { 

public static void main(String[] args) throws Exception { 
    Agent agent = new Agent(); // A simple ICE Agent 

    /*** Setup the STUN servers: ***/ 
    String[] hostnames = new String[] { "jitsi.org", "numb.viagenie.ca", "stun.ekiga.net" }; 
    // Look online for actively working public STUN Servers. You can find 
    // free servers. 
    // Now add these URLS as Stun Servers with standard 3478 port for STUN 
    // servrs. 
    for (String hostname : hostnames) { 
     try { 
      // InetAddress qualifies a url to an IP Address, if you have an 
      // error here, make sure the url is reachable and correct 
      TransportAddress ta = new TransportAddress(InetAddress.getByName(hostname), 3478, Transport.UDP); 
      // Currently Ice4J only supports UDP and will throw an Error 
      // otherwise 
      agent.addCandidateHarvester(new StunCandidateHarvester(ta)); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    /* 
    * Now you have your Agent setup. The agent will now be able to know its 
    * IP Address and Port once you attempt to connect. You do need to setup 
    * Streams on the Agent to open a flow of information on a specific 
    * port. 
    */ 

    IceMediaStream stream = agent.createMediaStream("audio"); 
    int port = 5000; // Choose any port 
    try { 
     agent.createComponent(stream, Transport.UDP, port, port, port + 100); 
     // The three last arguments are: preferredPort, minPort, maxPort 
    } catch (BindException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IllegalArgumentException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    /* 
    * Now we have our port and we have our stream to allow for information 
    * to flow. The issue is that once we have all the information we need 
    * each computer to get the remote computer's information. Of course how 
    * do you get that information if you can't connect? There might be a 
    * few ways, but the easiest with just ICE4J is to POST the information 
    * to your public sever and retrieve the information. I even use a 
    * simple PHP server I wrote to store and spit out information. 
    */ 
    String toSend = null; 
    try { 
     toSend = SdpUtils.createSDPDescription(agent); 
     // Each computersends this information 
     // This information describes all the possible IP addresses and 
     // ports 
    } catch (Throwable e) { 
     e.printStackTrace(); 
    } 

    /*The String "toSend" should be sent to a server. You need to write a PHP, Java or any server. 
    * It should be able to have this String posted to a database. 
    * Each program checks to see if another program is requesting a call. 
    * If it is, they can both post this "toSend" information and then read eachother's "toSend" SDP string. 
    * After you get this information about the remote computer do the following for ice4j to build the connection:*/ 

    String remoteReceived = ""; // This information was grabbed from the server, and shouldn't be empty. 
    SdpUtils.parseSDP(agent, remoteReceived); // This will add the remote information to the agent. 
    //Hopefully now your Agent is totally setup. Now we need to start the connections: 

    agent.addStateChangeListener(new StateListener()); // We will define this class soon 
    // You need to listen for state change so that once connected you can then use the socket. 
    agent.startConnectivityEstablishment(); // This will do all the work for you to connect 
} 

}

Ce code nécessite que le serveur SIP soit configuré et que celui sur le test ice4j dise quelque chose d'autre regardez simplement Ice.java

+0

Je ne me rappelais même pas ce fil était toujours là. Merci d'avoir répondu! Je vais bientôt m'en occuper, et je vais certainement vous envoyer un e-mail. – RaKXeR

+0

Jetez un coup d'œil à [UDP Hole Punching] (http://stackoverflow.com/questions/27129268/udp-hole-punching-java-example) –