I am trying to create a java chat application for my networking class. As of right now I am stuck trying to connect to someone behind a different router. The way I have my project right now is I have a client program and a server program. The client programs first logs into the server program which logs their IP and port in a database and then the server gives them back the list of their friends with their IPs and ports. Then the client closes down the connection to the server and tries to connect to another client using the information the server sent back. So far my program only works connecting to the server and getting the friends IP and port but when I use those values to connect to the other client I cant connect.
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();
Above is a snippet of java code used to connect to the server then below is what i do on the client side.
ss = new ServerSocket(reusePort);
So now technically I am listening on the same port I used to connect to the server with which is logged in and is retrievable to another client and is in the NAT table with my ip and port. I am not sure what I am missing or if there is some protocol or something that I have to do. I have looked at TCP and UDP hole punching but I am not sure how that is actually accomplished or how to implement it.
Any suggestions would be appreciated.
If you want to send a message you'll need to set up port forwarding on any device that acts as a server (any device which creates a socket server). Port forwarding is done on the Router. The reason you cannot connect to the other client is because they are hidden behind their routers firewall. Their address to the rest of the world is actually the address of the router, not of their physical computer. On their local network they have a different address then what the rest of the world sees, and the router figures out what messages from the outside world need to be sent to the client based on an address translation table.
Given your architecture, this would mean that all clients need to have their routers doing port forwarding, which is of course unfeasible (imagine gtalk or aim requiring users to do port forwarding).
The more common architecture is to have the Server do the work of rebroadcasting messages to the connected clients and maintain tables to lookup whose talking with who. This way there is a single server which will need a static ip (or be port forwarded), and all users are simply clients which connect to the server socket and read messages from it.
For actual code describing the second architecture please see http://pirate.shu.edu/~wachsmut/Teaching/CSAS2214/Virtual/Lectures/chat-client-server.html. Then the machine which is running the server code either needs a static ip or if it is behind a router needs traffic from the port it is listening on to be forwarded.
So on the server code you will bind to the ip assigned from your router (something like 192.168.1.2 at some port say 5000). Then go to your routers configuration page (it may be 192.168.1.1 see http://www.wikihow.com/Port-Forward/Open-Ports-on-a-Linksys-Router), and forward port 5000 to the address 192.168.1.2.
The Interactive Connectivity Establishment (ICE) protocol combines various NAT traversal utilities such as the STUN and TURN protocols in order to offer a powerful mechanism that allows Offer/Answer based protocols such as SIP and XMPP to traverse NATs.
This project provides a Java implementation of the ICE protocol that would be usable by both SIP and XMPP applications. The project also provides features such as socket sharing and support for Pseudo TCP.
ice4j is maintained by the Jitsi community.
ice4j
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With