I am trying to make an online game application, which communicates with another pc peer-to-peer over the Internet.
Since both pc's are likely to be under NAT, and since I cannot afford an external server, I thought the only way is to use free STUN and TURN server, such as Numb.
However, after some research, I couldn't figure out how to use those servers to make a connection.
Is it really possible to use only those servers to do it? If it is, how would you do that?
Or is there an easier way of doing that?
I can use either UDP or TCP for this.
Take a look at the Internet Gateway Device Protocol. Is is an extension to the UPNP protocol, is very easy to use, is supported by pretty much every router out there and there are some free libs implementing this protocol.
Related
I am attempting to make a chat application on the .NET framework that will be able to communicate over the internet and not just LAN. I would like it to be P2P as to not require a central server. I don't mind which protocol it uses (UDP, TCP, etc) so long as I can send messages to almost any given IP.
All I would like to know is how to send data to another IP I know of, nothing else. I've searched around but the code is too complicated for me. (For example I've looked at the source code for torrent clients).
Help will be appreciated a lot thanks.
P.S.: I've heard about a method called UDP hole-punching if that sparks any plugs.
There is a small issue with your plan.
The server-centric approach does not serve only as a slow middle man, but also as a central point with known address to connect to, an anchor in the sea to attach to and clients connect to the static IP/name of the server.
Usually, users do not care what is their IP address on the internet...
So at the minimum, the server is good to get list of clients.
Nowadays you can use some services from Microsoft or Google or other.
Now rest of the P2P communication of clients between NAT comes with more learning: TCP_hole_punching
I would suggest reading all that stuff then look for some code or library that does it.
Here is older topic similar to yours looking for the hole punching library: tcp hole punching library
I have answered similar kind of things here Peer-to-Peer application using java, let me know if it helps or if you have any specific question about this. Basically you need NAT traversal, so you would find many different ways to achieve this based on your need. Even you can achieve this simply configuring your router by enabling UPnP.
I wrote a client-server application designed to exchange files (among other things) over the local area network. In server mode, the application listens for TCP connections with a specific identification header. In client mode, it tries to establish TCP connections to IP Addresses that are provided by the user.
I now need to adapt this application to work over the internet. Without much exposure to network programming, I am not sure how to achieve this without some kind of a central server (for announcing presence, etc.). This is not an option.
Suppose I have the app running in server mode on my machine which is behind a home network. You (the reader) have the app in client mode and we need to connect. Neither of us have static IP addresses. Is there a way for the client to reach the server? Both the server and client could figure out their public IP addresses but beyond that, I'm not sure what to do.
Any guidance would be appreciated.
EDIT: Based on the answers, some clarification is in order. My question is not about discovery. Both client and server can query their public addresses and users can exchange these IPs over some other medium. The question is, how to establish a connection once each other's IPs are known but both parties are behind networks which do not have the appropriate port forwardings. My app uses port 51200 as a default over TCP for example.
I've learned that the techniques of UDP hole punching to obtain a true direct connection between 2 peers, is imperfect due to some possible combinations of NAT types involved. What this means is that UDP hole punching alone is not always going to work.
The way to claim 100% operability is to, in the cases where a p2p connection is impossible, use a relay server. The process of discovering whether a true p2p connection is possible has been standardized by ICE,TURN,and STUN. All I know is that using ICE/TURN/STUN seems to be the standardized strategy in subverting the NAT problem. It can facilitate a true p2p connection when available and offer relaying services when necessary.
Note: I use the term p2p in this answer to distinguish a truly direct connection between 2 endpoints, not to be confused with overlay networks and the like.
Advanced Users: It is possible to gain more direct p2p connections by introducing more complicated strategies to cooperate with symmetric NAT behaviour, such as port prediction, etc. But the libraries that implement these methods are costly, and seems too difficult for a DIY job.
I have not explained in detail the different types of NAT connection possibilities. You will want to research on NAT types and how they relate to UDP hole punching. There are RFCs out there and I will try to update my answer with links. But the point is that you can avert a lot of this learning by refocusing on implementing TURN/STUN/ICE, learn how they are implemented and how you can use their standardized behavior.
Potential Solutions
PJSIP - contains a stand-alone high level NAT traversal library for C/C++, also has bindings for other langauges. If you just want the NAT Traversal library sub-component, see PJNATH
LibJingle - a P2P (peer-to-peer) and RTC (real-time communication) stack that builds on XMPP. Note that many of LibJingle implementation is not interoperable with actual XMPP Jingle specification and subsidiary specifications.
These may add considerable complexity to the program, which is why it can be compelling to implement some of the mechanisms myself.
Documents
NAT on Wikipedia
NAT Traversal Fundamentals
How NAT Compatible are VoIP Applications
STUN server list
Teredo/Shipworm Doc
Symmetric NAT and UDP Hole Punching
STUN/TURN/ICE Summary
IETF
RFCs
RFC 5245 – ICE
RFC 5389 – STUN
RFC 5766 – TURN (iirc, TURN uses a STUN server.)
RFC 5768 – ICE – SIP
RFC 6336 – ICE – IANA Registry
RFC 6544 – ICE – TCP
RFC 5928 – TURN Resolution Mechanism
RFC 6062 – TURN Extensions for TCP Allocations
RFC 6156 – TURN Extension for IPv6
[Draft] Symmetric NAT Traversal using STUN
[Draft] Network Address Translation and Peer-to-Peer Applications (NATP2P)
Microsoft
MS-STUN – Microsoft STUN extensions
MS-TURN – Microsoft TURN extensions
MS-ICE – Microsoft ICE extensions
MS-ICE2 – Microsoft ICE2 extensions
Notes
I have heard that the eventual migration to IPv6 may squash the NAT traversal problem, but [probably not]. Someone could enlighten this topic. Either way, the progression to IPv6 appears slow from my non-experienced viewpoint, and I wouldn't count on it as a solution.
Few months ago I was looking for a similar solution, but unfortunately I got stuck and henceforth I dropped it.
People say you could use UDP hole punching or TCP hole punching, but I was unable to do this (I'm not a specialist in computer networks though). Whether it will work or not depends on the network itself.
Here is the question I originally asked, maybe it will be helpful to you. Honestly, I don't want to kill your hopes, but I'm afraid it may be a dead end. :(
I don't believe this is possible without some sort of central place to "find" each other. You need some way for the client the find the servers ip address to connect to.
Also, udp or tcp hole punching is an entirely different thing and uses, guess what: a central server.
If you use IPv6 it is possible - but you still need to know the other parties address. It also is possible if you use a DynDns service - but that is already a kind of central infrastructure.
That's it. It's a newbie question, probably. I'm almost giving up on TcpClient/Listener because of NAT and firewall issues. I wanted to know if theres an alternative. port 80 probably doesn't have to deal with any of these annoying things. I hope the answer is Yes.
What about the SignalR over WebScockets
Yes, you can implement WebSockets in a non-browser application, but it won't solve your problem.
When you try to open a server listening to websocket connections, you will run into the same problem you ran into when you created a normal socket connection: Personal firewall solutions will get in the way and not every router will forward the port you've chosen. Using the well-known port 80 won't help you here. It is quite uncommon for normal consumers to have a webserver running behind their NAT router, so by default no NAT router will forward the port unless specifically configured to do so.
A NAT router will generally prevent any hosts behind it to act as servers unless configured to allow it. When you want the users to not worry about their NAT configuration, both users must act as clients. The only way to do this is by having a central server all players connect to.
While hosting a server is still not free, it has become quite cheap due to cloud-based hosters who will rent you small, virtualized servers for very modest prices. The smallest instance from Amazon EC2 only costs you 2 cents per hour or $14.40 per month. Or you can build your own server from some spare-parts and host it on your own internet connection. When you don't have a static IP address you can use a dynamic nameserver service like no-ip or DynDNS.
Yes you can, but please don't.
I would suggest to change your architecture:
Use a server socket as a main point to handle clients. This server has to have a visible IP/port. In this case you may have clients behind nuts, and do not bother.
I have a server & a client. The client is my Android phone. The server is my PC running Windows.
I'm needing to find out the best programmable method of sending a short string to the PC and having it displayed real-time.
Please keep in mind the only languages I can program in on my server-side is VB.NET, C#, and C++ (and my experience with them is in that order).
Edit:
I don't care about security or anything. Both devices will be on a private wifi network. I can't rely on 3rd party applications though, considering the computer running the server will have very little RAM.
If it's just a simple string, and you don't care too much about security or reliability, you could go about this using java.net.Socket. Create a Socket, giving it your PCs IP address, an open port, etc. Write up an application on the PC to listen to that port, and handle the data as it would. I have no idea how you would go about doing the server-side part, as I've only really used Java, but it shouldn't be that hard if you're going with raw sockets. With the Socket on your android, create an output stream, and pass the string through that stream.
If you need a more secure, more reliable, more standard protocol of delivering a string, I'd probably go with HTTP. You might have to read up more about it, but they're better overall. Sockets aren't a whole lot simpler, though.
You can write a .NET project which communicates with sockets. Your PC could listen to a given port and your phone would access that port. This article might help you to learn more about .NET socket programming and you will be able to use C# or Visual Basic as you want.
Im sorry if this been asked before, but couldnt find anything about this particular matter.
I try to find out with which of my own ip's my computer use to connect to a remote ip.
I use some kind of socket setup both ways etc, and im sending my ip (and other stuff with xml) to another server so it knows how to contact me.
But how do i figure out which ip i should send to it?
I have the servers ip or host name, but trying with
Dns.GetHostEntry("host").AddressList
But that only gives me the ip of the remote host and not how my computer reach it.
Is my question solveable at all or is this just wishful thinking?
Can you have the remote host capture that data? That end would surely have it.
If you're using UDP then this is exactly what the STUN protocol was designed for. STUN is used in VOIP applications (among other P2P systems) to be able to tell what a specific connection looks like on the internet.
One very reliable .NET implementation that implements STUN is included in the Lumisoft.NET library (source code available here). I've used it myself for to satisfy this specific task for applications ranging from VOIP to P2P VPN alternatives. It is very easy to use and is standards compliant.
NOTE: I am NOT in any way affiliated with Lumisoft, I've merely used their library in several different applications
Ok, quick update that wont help anyone except myself.
But.
Found out that i can send hostname instead of actual ip, will work for now and most cases, and let the DNS do what its suppose to do :)