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.
Related
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.
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.
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 :)
Is there a way to create a sip network with multiple telephone numbers and just one public telephone? Do I need to have a sip server for this? Can someone give me some ideas? If I need a sip sever how can I create one? I am new to this stuff.
Thanks.
Creating a SIP server will be rather difficult if you're new to it.
A better way to familiarize yourself with SIP may be to get yourself an old computer and install something like asterisk, or Trixbox community-edition, then work on developing a sip softphone.
The asterisk/trixbox server will then take care of all of your telephone extensions and incoming trunks (I recommend sipgate for incoming trunks, free with 15 simultaneous incoming calls).
There are a lot of open-source sip softphones knocking about, as well as some free .NET sip libraries that you can work with, some of which are discussed here. This will at least help in becoming more familiar with the SIP protocol.
I know this is probably not the answer you were looking for, but I do hope it helps.
If you mean can you have mutliple SIP devices (softphones, ATAs IP Phones etc) all sharing a single PSTN number then the answer is yes. Almost all SIP/VoIP Providers allow you to forward calls from an attached DID (telephone number) to more than one SIP device so your request could be satisfied by a basic account on your friendly neighbourhood VoIP Provider.
Since you included the C# tag you maybe interested in looking at sipsorcery.com which is a project I run and which is based around an open source C# SIP stack.
I am looking forward to make a sort of a chat application using C# and WCF, yet before I start I wanted to clear a few things, so that I don't get carried in the wrong direction. :)
the application should be able to both make event ( send messages ) and listen to events ( receive messages ), therefor if I understand it right, the application should be both the client and the server at once?
what binding should I use? If I understand right, basicHttp binding hard to configure and is used when a WCF app needs to connect to non-WCF app? While for connecting two WCF apps its better to use NetTcpBinding?
how would this applications find each other, considering that they are running on different machines? should there be a central server, to which the app would connect first, saying "I'm user123, my IP is that and that, I'm free for chat" and look for other user IP addresses there? Or is there some other ways for apps to find each other without the central server?
maybe you could direct me to some examples or tutorials on this topic? ( tried googling, no luck ).
Thanks! :)
If your peers (machine that can operate as a client & server) are going to be behind NATs/firewalls then you will have a very very tough time building a chat application using WCF. If the peers will all be on the same network WCF is workable.
To write a chat application from scratch using WCF you will be re-inventing the wheel. Why not employ an existing protocol that's been designed precisely for the purpose such as XMPP. There are XMPP libraries around for .Net. You will need a central server but if you use XMPP you could feasibly piggyback onto one of the many existing free servers.
You can use netPeerTcpBinding.
See also:
http://blogs.interknowlogy.com/2009/08/05/building-a-really-simple-wcf-p2p-application/
http://msdn.microsoft.com/en-us/library/bb690929(v=vs.90).aspx
http://www.codeproject.com/KB/WCF/Chat_application_using_WC.aspx
There is no right and wrong answer to your question - it all depends on what you require. You then can choose the best architecture for your needs, and then the best technology for that architecture.
There are two things to consider - how will users find people to chat to, and then once they have found someone - how do the applications connect to each other.
For users to find each other, you either need to connect to a central server, which will then show a list of all connected users, or users need to enter the IP address of the person they want to chat to. Note that some firewalls will block incoming connections in this second case, so this may not be feasible in some cases.
Next, once you have found the person you wish to chat to, you need to decide whether messages will route directly to the other user, or if you want to continue to go through a central server.
If you choose to go through a central server, then your application will be functioning as a client, and will therefore pass through firewalls without a problem. However if you connect directly to the other user, both copies of the application will be acting as a client and a server (P2P topology), and therefore firewalls may be an issue. Having said that, you could designate one of the applications to be a server, with the other acting as a client, in which case only the server side needs to worry about the firewall.
Without knowing exactly what you are trying to achieve, it is hard to recommend which architecture will work best for you.