I am creating an application that listens for connections (server) from a different application (client) via a tcp connection. So if both application where to be on the same network it will be easy to establish the connection. so I am trying to add a method to the server so that users do not have to open ports on their routers in order to make the app work when using it over the internet. so let me show you a few different scenarios:
1)---------------------------------------------------SCENARIO_1-------------------------------------------------------------
the server is a computer in a house. That computer is connected to a router and that router is connected to the internet. The client is a computer on a office that has access to the internet as well.
for this scenario to work, before I used to open the ports on the house router and forward them to the server computer. on the client I just had to supply the correct IP address and same port in order to establish the connection.
now I avoided opening the ports on the house router with a really cool technique:
first I add this reference:
then I tell the router which ports I want to be forwarded to my computer (the server):
NATUPNPLib.UPnPNATClass upnpnat;
NATUPNPLib.IStaticPortMappingCollection mappings;
public ServerExample()
{
InitializeComponent();
// server local IP address
mappings.Add(1300, "TCP", 1300, "192.168.0.120", true, "my server");
//.... etc
..
when doing this I am able to connect from my office computer by providing port 1300, the WAN ip address of the server computer which is a different one. (that address can be found at: whatismyipaddress.com) THE COOL THING IS THAT I DO NOT HAVE TO DO ANY CONFIGURATION ON THE ROUTER!!!
2)-----------------------------------------------SCENARIO_2----------------------------------------------
know here comes my problem. The server happens to be on a office. that server is connected to router A, router A is connected to router B and router B is connected to the internet. In other this example is like the last example on the server with an extra router in between. and the client is somewhere else. we do not care how the network setup is on the client computer as long as it has internet access.
the way I used to solve this was by forwarding the packages from router x to the server computer and also port forwarding the traffic from port x of router B to the ip address of router A. when setting up that configuration I was able to establish a connection with the client when providing the WAN ip address of the server. (the ip address that is shown at: whatismyipaddress.com when retrieved from the network of the office).
so it will be nice if I can avoid doing all this configuration on the routers and do something similar to:
public delegate void SomeDelegate(string parameters);
NATUPNPLib.UPnPNATClass upnpnat;
NATUPNPLib.IStaticPortMappingCollection mappings;
public ServerExample()
{
InitializeComponent();
// server local IP address
mappings.Add(1300, "TCP", 1300, "192.168.150.141", true, "my server");
mappings.Add(1300, "TCP", 1300, "another ip", true, "router's ip");
so I have been playing around with that and I have not been able to make it work. also it will be nice if I could find out if the server connection is like scenario 1 with c# or scenario 2 or maybe a different scenario so that the users setting up the server do not have to specify all that info. for example I am sure that limewire does something similar.
Edit:
here is scenario 1 illustrated:
and here is scenario 2 illustrated
The feature that you are using is called Universal Plug and Play (UPnP) which is basically a way for a device to tell another device how to communicate with it. What you are doing is telling a computer to tell the router what ports you want forwarded to it. Unfortunately UPnP is a non-routable protocol which means that it can't jump across routers. So the short answer is that doing what you are trying will not work with multiple routers without manually configuring the ones "farthest" away from the client.
It might be possible to do something with Internet Gateway Device protocol (IDG) but you'd have to research that more and the library you are targeting doesn't support that. Post this question to Server Fault and you might get a better answer. (Don't post your code, just explain the basics of your problem, that you're trying to have a machine register itself with a router using UPnP which is working but you have another router in front of that that you want to automatically forward, too.)
Related
I'm working on a simple c# messenger and its works on the local network only. Does somebody know what should i do to make it works on the internet?
The solution contains the server project that listening on a certain port, and a client project connect to the server with that port.
Your clients need to be able to communicate with the server, which means that either:
You need to host the server application on a computer that is directly connected to the internet.
You need to setup port forwarding on the router that controls internet access for your network.
In either case the clients will need to know the IP address to connect to, and any firewall interactions need to be considered. This may also include ISP firewalls, as some ISPs limit inbound connections to subscriber connections.
I won't go into the specifics of setting up port forwarding on a router... there are plenty of examples, and every router is different. Google will help you with this if necessary.
Ideally you should have a static IP address for this, or some method for the clients to locate the IP address that your server is hosted on. If you must run from a dynamic IP address (such as some ISPs still use for subscribers) then one of the Dynamic DNS options might work for you.
In-order to make it work on Internet a simple answer is you need to enable ports which is used for communication.Generally the ports will be blocked by the Companies firewall for security reasons.So contact your IT dept to enable the port.
Or Use common port like 80.
OK so I've just started messing with TCP using c#, and I've successfully set up a server that i can send a 'Hello World' Message to, anyway I've been doing this locally (because both laptops are connected to the same router) i just use the 192.168 number to connect. but The whole purpose of it is to work over the internet, and the routers ip address is obviously the same for both computers, if i type the routers IP address it doesn't work, and if i type the 192.168 number that definitely won't work over the internet... So what IP do i use, or what is a better solution?
here's the line of code if it matters
var client = ScsClientFactory.CreateClient(new ScsTcpEndPoint("192.168.1.142", 10085));
Where 192.168.1.142 is the local ip of the laptop with the server started on it
and 10085 is the port.
You have to configure your router to forward any incoming connection to the port 10085 to you local IP adress. Then anyone will be able to connect using your external IP adress.
Each router has it's own configuration system so you have to search "port forwading" and your router model in google.
It depends on what your trying to acheive i guess. If for example your making a chat application. The client (behind the router) lets say its local IP is 192.168.1.111 and router IP is 80.120.78.100. The client would connect to the server.
Once that connection is made it doesn't matter about sending back to the client because the connection is already open between client and server so the server would just use the same connection. The router figures out where to "route" the packet, stuff which generally you dont need to know about.
If however your server is the one looking for clients, then thats different.
I'll try to explain a little about networks, but you'll have to search about it.
Basically, understand an IP mask, such as 192.168.1.0 as one network. Router's role is to connect different networks, that's why a router typically has 2 ports, WAN (wide) and LAN (local).
With this concept, you can see the internet as one big network made from the connection of various ISPs. Each ISP has a router to its network, and another one that gives you an internet connection. Finally, you have a router at your home. So, from this, you can understand that there are 3 networks connected: your home, your ISP and the internet.
In order for you to be able to connect to a computer at my home, I have to make this computer available from the internet, I have to publish it. I do this by setting up a NAT (network area translation) at my router. This NAT says "anything that comes from the internet on port 12345, forward to 192.168.1.10 (my server) at port 80".
This is an extremely simple explanation, ok?
Now, let's take a big step back. If you have another computer available on your network, you can test if your program is working with a much simpler approach.
Connect both computers to you LAN, so they will acquire similar IP addresses. Let's pretend they are 192.168.1.10 and 192.168.1.20
Run the server at 10 and disable all kind of firewalls (Windows and third party)
Run the client at 20 and try to connect to the server
I am trying to make a winforms client/server chat application. I already have a client and a server, both are working fine, i can log in, send messages, etc .. The problem is that it only works if i connect to my local IP. When i try to run the program with my external IP, i get the following error:
"The requested address is not valid in its context".
In other words, i can run the server on my own computer, start up (for example) 3 clients and let them connect to the running server. This basically means that i'm talking to myself. What im trying to do is to run the chat server on my computer, and let other people run the client-program and connect to the server through the internet.
this is the part where i get an error when i enter my external IP:
public void StartListening()
{
// Get the IP of the first network device, however this can prove unreliable on certain configurations
IPAddress ipaLocal = ipAddress;
// Create the TCP listener object using the IP of the server and the specified port
tlsClient = new TcpListener(ipaLocal, 50702);
// Start the TCP listener and listen for connections
tlsClient.Start(); <--- THINGS GO SOUTH HERE
// The while loop will check for true in this before checking for connections
ServRunning = true;
// Start the new tread that hosts the listener
thrListener = new Thread(KeepListening);
thrListener.Start();
}
im not sure if what i'm trying to do is possible? i can't imagine it is, but i kinda dont know how to proceed with this. I'm new to network programming so any help will be appreciated.
kind regards,
Jane
Jane,
I think your issue is with your IP address setup. This is a network connection problem. You need external IP address so that outside clients can contact your PC. You need more advanced networking. The IP address provided from you ISP is used for domestic uses. You need specialized public IP address so that clients can find you outside of the firewall. This is networking/ISP/external IP issue.
Your server application needs to listen to incoming connections on a specified port, on a specified locally installed NIC. That is why TcpListener always needs to be created using a local IP address: because it only cares which NIC (if you have multiple installed) it should use.
The MSDN page for TcpListener also states it explicitly:
TcpListener Constructor (IPAddress, Int32) Initializes a new instance of the TcpListener class that listens for incoming connection attempts on the specified local IP address and port number.
External IP address is completely irrelevant to a TCP/IP server. You can have numerous routers and network devices along the way, which can then forward incoming connections to your machine.
Just do make sure that your firewall and router are configured properly to allow incoming connections on a specified port. To do that, start your TCP/IP server to open the port, and then use a service like CanYouSeeMe to see if server can be reached from outside.
Regarding your comment (this can prove unreliable on certain configurations), it's obviously "unreliable" when you think about it: a laptop can easily have an Ethernet network controller with a completely different IP address than a Wifi network adapter. Your server app should allow the user to select which IP address to use, instead of picking the first address it gets.
I am using lidgen-network library 3 to try and create a peer to peer connection. I am new to network programming which is why i'm using this library.
Using the DiscoverKnownPeer() function i have been able to connect within my network. What i have read online is that i need to do a NAT punchthrough which requires a running server that is outside the router. I am hoping for a solution that doesnt require this extra server.
If i can store both ip addesses on a web server, and get create a web service to send the ip's to each respective client through XML, would I be able to create a peer to peer connection?
Thank you in advance.
No, you won't be able to establish a connection through NAT without a rendezvous server
NAT stands in your way because even if you know the IP address, that only gets you as far as the router. The router receives a request coming from the internet, and doesn't know which internal IP to send it to, so it throws it away.
NAT punchthrough works by making both peers send outgoing request to each other, the router then "knows" that packets directed at its public IP on the given port should go to the given computer.
So, you need to connect both computers to an external server not behind NAT, and then use that external server to coordinate connecting the two NAT obscured peers together (this is the peer introduction thing that Lidgren has built in).
I know this is old but...
You didn't specify that using the DiscoverKnownPeer() was necessary in your setup. If it isn't then you can setup peer to peer by appplying port forwarding rules in your router.
I want to know how I can send or recieve data over internet to/from a computer in subnet
(this is specially in context to PPP users bcoz getting static IP is not so much in practice).
I actually want to create an application which can transfer file between 2 specific computer in WAN.
so what are things I need to know about to do the same..(ex. PRESENT IP or MAC ADDRESS etc..)
PROGRAMATICAL EXPLANATION ALTHOUGH PREFFERED,BUT IS NOT NECCESARY...
FTP?
There is a vast torrent of useful results in google, I seriously suggest to google before you ask here.
For instance, have a look at the top result: http://www.devarticles.com/c/a/C-Sharp/Network-Programming-in-C-sharp/
Apart from that, FTP, as suggested by Colin, may be what you're looking for. If you're new to using FTP in C# have a look at http://www.google.com/search?q=c%23+ftp
Put the information on a public IP server, so both computers keep polling if there is new data and send / download that data as needed. A single text file can hold necessary flags such as paths and other info you need.
server just need to be a web server, which means IIS or similar should be installed.
I'm thinking part of your question has to do with one of the computers not having a static IP address. If the two computers, A & B, don't know each others IP address, then an alternative is to use a server. Either A can store the information on the server to be picked up by B, or A can register his current IP address on the server for B to lookup and then connect to A, assuming firewalls don't interfere. Another scheme is that A and B can simultaneously connect to the server, and the server can relay data between the two.
Of course, all of this communication would be done using techniques such as those suggested by mafutrct and Colin.
This question sounds to me like the difficulties of NAT Traversal and trying to establish peer-to-peer connectivity over the Internet. I stumbled on this question researching the best way to set up Internet connectivity to a device that is sitting behind a firewall. I am assuming that the device behind the firewall has to initiate the connection, that a Internet server application (on a Public IP address) to at least manage the initiation of the connection is required, and the Internet server application may also have to act as a relay if the difficulties of NAT is not able to be traversed.
http://en.wikipedia.org/wiki/NAT_traversal
http://en.wikipedia.org/wiki/Peer-to-peer
A good example of this is LogMeIn. Where the application is installed on the computer that needs to be accessible over the Internet, that application communicates with the LogMeIn Internet servers, you can establish a connection to that computer either by initiating through the LogMeIn servers and connecting peer-to-peer over port 80/443 using NAT Traversal (this would be establishing a peer-to-peer connection) or by initiating through the LogMeIn server and the LogMeIn server acting as a relay if peer-to-peer is unable to be established.
Please note; you must have an application (something running) on both ends of the connection on the Internet, there is no other way. Just like FTP that was mentioned earlier (FTP Client, FTP Server)... but in this case it is peer-to-peer (basically you are writing your own Client and Server... or if you have to use a relay... Client--Relay--Server
http://en.wikipedia.org/wiki/LogMeIn
"The service connects the remote desktop and the local computer using SSL over TCP or UDP and utilizing NAT traversal techniques to achieve peer-to-peer connectivity when available."
The part I don't know is can the relay go in both directions; and I am figuring the device behind the firewall must have to constantly manage the open connection to the Internet Server that is the relay. Those are the questions I am wrestling with now.
Also, you may want to check out this post.
C# byte streams through TCP
From that time, till this date I have encounter so many problems with these four kinds of NAT that basically without an external server you cant do anything.
This is because, one computer can never find where the other one is located as suggested in the pic.
Here PC 'A' will never come to know about the port that corresponds to PC 'B' on R2B without an external server.Even more, if somehow u come to know about the ports you are still in a situation that the router wont allow you to access it if the request hasn't been made for your IP.