2013-04-10 10 views
5

Sto provando a creare un'applicazione di chat java per la mia classe di rete. A partire da ora sono bloccato cercando di connettersi a qualcuno dietro un router diverso. Il mio modo di avere il mio progetto adesso è che ho un programma client e un programma server. I programmi client prima si registrano nel programma server che registra il loro IP e la loro porta in un database e quindi il server restituisce loro l'elenco dei loro amici con i loro IP e le loro porte. Quindi il client chiude la connessione al server e tenta di connettersi a un altro client utilizzando le informazioni restituite dal server. Finora il mio programma funziona solo collegandosi al server e ottenendo l'IP e la porta degli amici ma quando uso questi valori per connettermi all'altro client non posso connettermi.Java nat traversal per l'applicazione chat

socket = new Socket(); 
socket.setReuseAddress(true); 
socket.setKeepAlive(true); 
socket.setSoLinger(true, 10); 
socket.bind(new InetSocketAddress(Port)); 
socket.connect(new InetSocketAddress(host, SERVER_PORT)); 
reusePort = socket.getLocalPort(); 

è al di sopra un frammento di codice Java utilizzato per connettersi al server allora sotto è quello che faccio sul lato client.

ss = new ServerSocket(reusePort); 

Così ora tecnicamente sto ascoltando sulla stessa porta che ho usato per la connessione al server con cui è collegato e è recuperabile a un altro client ed è nella tabella NAT con il mio IP e la porta. Non sono sicuro di cosa mi manchi o se c'è qualche protocollo o qualcosa che devo fare. Ho dato un'occhiata alle perforazioni TCP e UDP ma non sono sicuro di come sia effettivamente realizzato o come implementarlo.

Qualsiasi suggerimento sarebbe apprezzato.

+1

Vedo che hai accettato una risposta, ma sembra che si vuole prendere in considerazione "Hole Puching". La risposta accettata in realtà non risponde alla tua domanda, ma ti dice invece di lasciare che tutte le informazioni della tua applicazione passino attraverso il tuo Server, e sembra che tu voglia connettere direttamente i tuoi clienti. –

+0

hey hai trovato la tua risposta. mi aiuti per favore. Sto avendo lo stesso problema. –

+0

Possibile duplicato di [libreria STUN, TURN, ICE per Java] (http://stackoverflow.com/questions/2039147/stun-turn-ice-library-for-java) –

risposta

1

Se si desidera inviare un messaggio, è necessario configurare il port forwarding su qualsiasi dispositivo che funge da server (qualsiasi dispositivo che crea un server socket). Il port forwarding è fatto sul router. Il motivo per cui non è possibile connettersi all'altro client è perché sono nascosti dietro il firewall dei router. Il loro indirizzo verso il resto del mondo è in realtà l'indirizzo del router, non del loro computer fisico. Sulla rete locale hanno un indirizzo diverso da quello che il resto del mondo vede e il router calcola quali messaggi dal mondo esterno devono essere inviati al client in base a una tabella di conversione degli indirizzi.

Data la tua architettura, questo significherebbe che tutti i client hanno bisogno che i loro router facciano il port forwarding, il che è ovviamente irrealizzabile (immagina gtalk o obiettivo che richiede agli utenti di effettuare il port forwarding).

L'architettura più comune è quella di fare in modo che il server esegua il ritrasmissione dei messaggi ai client connessi e mantenga le tabelle per cercare chi parla con chi. In questo modo c'è un singolo server che avrà bisogno di un ip statico (o di un port forwarding), e tutti gli utenti sono semplicemente client che si collegano al socket del server e leggono i messaggi da esso.

Per il codice effettivo che descrive la seconda architettura, vedere http://pirate.shu.edu/~wachsmut/Teaching/CSAS2214/Virtual/Lectures/chat-client-server.html. Quindi la macchina su cui è in esecuzione il codice server ha bisogno di un ip statico o se è dietro un router ha bisogno di traffico dalla porta che sta ascoltando per essere inoltrato.

Quindi sul codice server si collegherà all'ip assegnato dal router (qualcosa come 192.168.1.2 su qualche porta dice 5000). Quindi vai alla pagina di configurazione del tuo router (potrebbe essere 192.168.1.1 vedere http://www.wikihow.com/Port-Forward/Open-Ports-on-a-Linksys-Router) e inoltrare la porta 5000 all'indirizzo 192.168.1.2.

+0

Grazie tigger! A partire da ora ho il mio server port forwarded a X dietro il mio router, sto pensando di passare alla seconda architettura che hai suggerito (grazie per il link, può essere difficile setacciare anche se a volte google lol) e avere ogni client mantenere un una singola connessione al server e al server quindi inoltra loro qualcosa attraverso di essa. Tuttavia, ho intenzione di pasticciare un po 'di più con quello che ho poi passare mentre sono a corto di tempo. Grazie per l'aiuto. – DarkLazar

+0

ok, quindi stai dicendo che non potendo andare su ogni router, passiamo e facciamo il port forwarding. quindi dovremmo usare un server e lasciare che faccia il lavoro. (Perfavore, correggimi se sbaglio). quindi cosa farà esattamente il server? per favore perdonami se la mia domanda è strana, io sono nuovo al networking. –

+0

@DarkLazar È così che funzionano i client torrent? O usano un altro modo per raggiungere questo obiettivo? C'è un modo più semplice per implementare questo? (come una biblioteca) – goodbytes

1

Il protocollo Interactive Connectivity Establishment (ICE) combina varie utility NAT traversal, come lo STUN e girare i protocolli al fine di offrire un potente meccanismo che consente protocolli di offerta/risposta based come SIP e XMPP per attraversare NAT.

Questo progetto fornisce un'implementazione Java del protocollo ICE che sarebbe utilizzabile da entrambe le applicazioni SIP e XMPP.Il progetto fornisce anche funzionalità come la condivisione dei socket e il supporto per Pseudo TCP.

ice4j è gestito dalla comunità Jitsi.

ice4j