2013-04-10 16 views
5

Próbuję utworzyć aplikację czatu java dla mojej klasy sieci. W tej chwili utknąłem, próbując połączyć się z kimś za innym routerem. Obecnie mam swój projekt: mam program klienta i program serwera. Programy klienckie najpierw logują się do programu serwera, który rejestruje ich IP i port w bazie danych, a następnie serwer przekazuje im listę swoich przyjaciół wraz z ich adresami IP i portami. Następnie klient zamyka połączenie z serwerem i próbuje połączyć się z innym klientem przy użyciu informacji odesłanych przez serwer. Do tej pory mój program działa tylko łącząc się z serwerem i uzyskując adres IP i port znajomych, ale kiedy używam tych wartości do połączenia z drugim klientem, nie mogę się połączyć.Java nat traversal do aplikacji czatu

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(); 

Powyżej znajduje się fragment kodu java służący do łączenia się z serwerem, a następnie poniżej, co robię po stronie klienta.

ss = new ServerSocket(reusePort); 

Więc teraz technicznie mam słuchać tego samego portu kiedyś połączyć się z serwerem, z którym jest zalogowany i można odzyskać do innego klienta i jest w tabeli NAT z mojego IP i port. Nie jestem pewien, czego mi brakuje lub czy jest jakiś protokół lub coś, co muszę zrobić. Przyjrzałem się dziurkowaniom TCP i UDP, ale nie jestem pewien, jak to się robi i jak go wdrożyć.

Wszelkie sugestie będą mile widziane.

+1

widzę zaakceptowaniu odpowiedzi, ale wydaje się, chcesz wyglądać na „Hole Puching”. Przyjęta odpowiedź tak naprawdę nie odpowiada na twoje pytanie, ale zamiast tego każe ci przekazać wszystkie informacje twojej aplikacji przez serwer, i wydaje się, że chcesz bezpośrednio połączyć swoich klientów. –

+0

hej, znalazłeś odpowiedź. proszę pomóż mi. Mam ten sam problem. –

+0

Możliwy duplikat [STUN, TURN, biblioteka ICE dla Java] (http://stackoverflow.com/questions/2039147/stun-turn-ice-library-for-java) –

Odpowiedz

1

Jeśli chcesz wysłać wiadomość, musisz skonfigurować przekazywanie portów na dowolnym urządzeniu działającym jako serwer (każde urządzenie, które tworzy serwer gniazd). Przekazywanie portów odbywa się na routerze. Powodem, dla którego nie można połączyć się z drugim klientem, jest to, że są one ukryte za firewallem routera. Ich adres na resztę świata jest w rzeczywistości adresem routera, a nie fizycznego komputera. W swojej lokalnej sieci mają inny adres niż to, co widzi reszta świata, a router określa, jakie wiadomości ze świata zewnętrznego muszą być wysyłane do klienta na podstawie tabeli translacji adresów.

Biorąc pod uwagę twoją architekturę, oznaczałoby to, że wszyscy klienci muszą mieć swoje routery przekazujące port, co jest oczywiście niewykonalne (wyobrazić sobie GTCAL lub cel wymagający od użytkowników przekierowania portów).

Bardziej powszechną architekturą jest to, że serwer wykonuje prace związane z retransmitowaniem wiadomości z podłączonymi klientami i utrzymuje tabele do wyszukiwania, z kim rozmawiają. W ten sposób istnieje jeden serwer, który będzie wymagał statycznego adresu IP (lub będzie przekazywany do portu), a wszyscy użytkownicy są po prostu klientami, którzy łączą się z gniazdem serwera i odczytują z niego wiadomości.

Aktualny kod opisujący drugą architekturę znajduje się pod adresem http://pirate.shu.edu/~wachsmut/Teaching/CSAS2214/Virtual/Lectures/chat-client-server.html. Następnie komputer, na którym działa kod serwera, potrzebuje statycznego adresu IP lub jeśli znajduje się za routerem, potrzebuje ruchu z portu, na który nasłuchuje, aby zostać przekierowanym.

Tak więc na kodzie serwera będziesz wiązał się z IP przypisanym z twojego routera (coś takiego jak 192.168.1.2 na pewnym porcie mówi 5000). Następnie przejdź do strony konfiguracji routerów (może to być 192.168.1.1, patrz http://www.wikihow.com/Port-Forward/Open-Ports-on-a-Linksys-Router), i prześlij port 5000 do adresu 192.168.1.2.

+0

Dzięki tigger! Zrobiłem jak dotąd mój port serwera przekazany do X za routerem, myślę o przejściu do drugiej architektury, którą zasugerowałeś (dzięki za link, może być ciężko przesądzać przez google czasami lol) i po tym, jak każdy klient utrzymuje pojedyncze połączenie z serwerem i serwerem przekazuje je za jego pomocą. Jednak mam zamiar zadziwić trochę więcej z tym, co mam następnie zmienić, jak mi zabraknie czasu. Dzięki za pomoc. – DarkLazar

+0

OK, więc mówisz, że gdy nie możemy przejść do każdego routera, przechodzimy i wykonujemy przekierowanie portu. więc powinniśmy użyć serwera i pozwolić mu wykonać zadanie. (Proszę, popraw mnie jeśli się mylę). więc co dokładnie zrobi serwer? przepraszam, jeśli moje pytanie jest dziwne, jestem nowy w networkingu. –

+0

@DarkLazar Czy tak działają klienci z torrentami? A może używają innego sposobu, aby to osiągnąć? Czy istnieje łatwiejszy sposób wdrożenia tego? (jak biblioteka) – goodbytes

1

Protokół Interactive Connectivity Establishment (ICE) łączy różne media NAT takich jak STUN i TURN protokoły w celu zaoferowania potężny mechanizm, który pozwala protokoły Oferta/Answer oparte takich jak SIP i XMPP przechodzić NAT.

Ten projekt zapewnia implementację protokołu ICE w języku Java, która może być używana zarówno przez aplikacje SIP, jak i XMPP.Projekt zapewnia również funkcje takie jak udostępnianie gniazd i obsługa Pseudo TCP.

ice4j jest utrzymywana przez społeczność Jitsi.

ice4j

Powiązane problemy