I am trying to build a system in java, where one computer acts as the server and the other one as the client and connect them together (i.e send data b/w them) on the public network. Here is my pseudo code -
Server.java
ServerSocket server = new ServerSocket(55955);
Socket socket = server.accept();
Client.java
Socket socket = new Socket("<ip address of server>", 55955);
//code to send and receive response from server
The code works fine if I have my server and client running on my computer.But if i run the server on a different machine (a friend's pc on the internet) and try to use that ip on the client running my machine, its not working. I did a lot of googling and did not find a appropriate solution other than opening up the firewall or ports on the machine.
Is there any other option to connect b/w the computers on the internet without any forwarding or opening the ports ?
There are a few peer to peer systems (eg: skype)etc that does the same thing I am trying to achieve (and in my best of my knowledge its without opening any ports on the host machine). Please correct me if I am wrong.
Thank you.
Thank you. I am adding the solution which I was finally able to work with.
This can be achieved using NAT Hole punching.
Found these awesome articles which explains the approach.
Peer-to-Peer Communication Across Network Address Translators
How Skype gets around firewalls
Related
I am trying to write a client-server app that connects a PC as a client to my PC as a server.
When I enter 127.0.0.1 as server IP in client side, in my PC, it works properly so it's not a coding problem. Also when I enter my IP (got it from nslookup command in kali) and connect to internet, client connects to server properly.
But when I open my client app in other PC and server app in my PC, the client side a "Connection Time out" Exception will be thrown.
I have tried turning off the firewall in the client side (Windows 10) but not from the server side.
Here are my codes:
Server:
ServerSocket server = new ServerSocket(SERVER_PORT);
Socket client = server.accept();
//Some codes
Client:
Socket server = new Socket(SERVER_IP, SERVER_PORT);
For better answer we need more informations from you. But from this what you post, this is best answer i can make. You didn't explain what is your goal, do you want to make connection inside local network or you would like to make connection to 'outside world', over internet.
If you like to make two PCs communicate inside local network, than you must make sure they are on same network, or more accurate, that they are connected to same router. You have to set your server IP address to IP address on your local network, that would probably be something like 192.168.xxx.xxx
If you want to communicate over internet, i suggest test in local network first, as described before. If it works on local network, then you have to deal with firewalls, router setting,etc to make it work on the internet too.
Take look at this too
Use Socket-communication over different networks
I have a simple java written client and server chat application(with sockets). When running on the same network/computer it works fine. However when i try to run the client from a different network it doesn't connect. I tried using the public IP address of the server to connect the client to the server but without luck. How would I be able to connect to the server app from a different network? any help would be appreciated.
It sounds like you have more of a firewall issue than a problem with the application. Instead of trying to connect with the Java client, first try connecting with Telnet to the server from the same computer, then from the other computer. The first effort will show you what to expect when it works. For instance, if your server is running on port 999, use telnet server.example.com 999.
If the machines are Linux boxes, use iptables -L to see whether there is a block on the port you are trying to access.
If you're still having problems reaching the server, run tcpdump -i tcp:999 on the server host to see what traffic is making it to your server socket, then run the telnet commands again. You should see the tcp connection established when connecting from the local machine, maybe or maybe not when connecting from other machines. If you don't see it while connecting from other machines, run tcpdump there too to make sure the client is definitely sending the traffic to the server.
After you are sure that the server can receive traffic and that your client is sending the traffic, there are no mysteries about what is actually going on and you should find your problem.
It worked after I did port forwarding on router. Most of the ISP provided modem/routers wont let you manipulate ports so had to buy my own modem/router, forwarded the port and worked like a charm. Information on what port forwarding is can be found here : http://www.howtogeek.com/66214/how-to-forward-ports-on-your-router/
Goal
I'm making a chat application for android and am currently testing with 2 phones which must eventually work for a few thousand users.
Problem
I get a ConnectionException saying "Connection refused" whenever the 2 phones try connecting to each other via sockets.
Current Design
Each phone starts a ServerSocket, calls the accept() method waiting for some Socket to connect to, and whichever phone sends a message first will create a client Socket. I'm certain the IP addresses I'm using are correct (they're actually both using the same external IP).
I believe the problem is with the ports. I generate a port number at random, and if it's free to use, I say ServerSocket s = new ServerSocket( randomPortNumber ).
What I think is the source of the problem
What I think is the problem is this port number is one sitting behind an NAT router. So when a Socket tries to connect to the ServerSocket using something like Socket socket = new Socket( ip, serverSocketRandomPortNumber ), it will try to connect to the NAT router and feed it this port number which won't work since the router itself is not listening on this port, but the phone behind the router is.
Questions and thoughts
My question is, how do I deal with this problem?
Do I have to change my design?
If I must, an alternative design I'm thinking of is using a single ServerSocket on a web host and use it to redirect messages sent from client sockets to other client sockets.
I'd be implementing the server-side in php referencing something along these lines:
http://php.net/manual/en/sockets.examples.php
And I would still use Java for the client-side.
Since one of the phones is behind a NAT router, nothing can initiate a connection to it unless port forwarding (or some other techniques) is enabled on the router.
The usual way a chat application is implemented is, there is a common server that all clients will connect to.
You don't have to write your own chat server (unless you really want to). I suggest using the XMPP protocol. A list of already made servers here. On the client side (Android), you can find libraries you can use here.
I created a Battleship game in Java to work with Sockets and ServerSockets. The game works fine on LAN, but I would like to be able to play against someone on a completely different network. I understand port forwarding would be necessary, but would I have to forward the port on every client that is playing the game? Or would it only be necessary to forward the port on the router the server is using? Thanks.
Port forwarding is only required on the server. Any packets bound for the client will be auto-forwarded from the initial request thanks to the action on many NATs.
So, you only need to forward the port on the server. If using Socket and ServerSocket you need to forward TCP if your router gives you the choice. If using DatagramSockets, forward UDP at either of the endpoints.
(if you had to forward on clients, you most likely wouldn't have been reading this page without forwarding port 80)
To elaborate on what #hexafraction is saying, here's what you can do:
Build a server that any client can connect to. Clients can generally connect to anything they want. Firewalls usually place restrictions on information that can flow in, but not flow out. So if the clients know the server to connect to, they can connect to it without modifying their firewall and then the server will coordinate transferring the data between the clients.
I did this and all I had to do was forward the port I was using in my router to my local I.P. address. If you don't know your local ip address run a command prompt (assuming your using windows ) and run ipconfig to figure it out. If your at home using a wireless router access it by browser to 192.168.1.1 Hope this helps!
I made application with java using socket. My computer is the server and my phone(android ) is the client. Only what i trying to do is to forward String from phone to client PC.
Everything works fine when i configure my router and open the port i using. i don't want every time when costumer will install my application will need to open port in the router.
I thought about using remote server that will run my server code. but i didn't find server that can do that . i don't want to make my pc a server for all costumers.
How does all the chats companies do it without open port?
You must look into UPnP. This is what /most/ if not /all/ torrent clients use to allow foreign connections, without forwarding ports. How chat clients do it is a different scenario. They use hacks such as firewall hole-punching using UDP (with an external server) http://www.h-online.com/security/features/How-Skype-Co-get-round-firewalls-747197.html see this link for details on UDP hole punching.
Also see this article http://www.codeproject.com/Articles/13285/Using-UPnP-for-Programmatic-Port-Forwardings-and-N for usage of UPnP. But this is in C++, but I think you will understand.
EDIT: http://4thline.org/projects/cling/ I found this. I think it can help you.
You had to open port probably because of your routers firewall :). If you already opened let us say port 9090 then every client app (android phone) will be able to connect to it :). Of course if somebody wants to install server on their own pc they would problably forward some ports and disable some firewalls. If you want server with no special requriements lookup VPS'es. :)