I'm creating a TcpListener, and I want clients from other computers to be able to join my listener.
I've read and understood that I have to do Port Forwarding, but it doesn't make any sense to me - when I publish my app, I want other people to create this Listener, and I can't tell them to do Port Forwarding.
Is there any possibility to create a TcpListener that clients will be able to join without Port Forwarding?
Thank you.
Well, lets try to clear somethings out first.
The main reason to use port forwarding is because you have a NAT router in front of an internal network. To setup a port forward is to instruct the NAT router to forward traffic to a certain port on the public interface to a port on an internal computer.
If you don't have a NAT router you don't need port forwarding.
Many routers today support UPnP, a technique to kindly ask the router to create a specific port forward. A suitable library to use might be ManagedUPnP.
However you still need to figure out the public IP of the router and what port you have opened and communicate that to your other applications.
If your router does not allow UPnP or there are other fire wall rules in place you can not set up a port forwarding correctly.
You can create server application and forward ports on your pc. Client application (this one you will publish) will just connect to your pc so they can be on the NAT. You can also combine your application with some php/asp pages but it depends on data you would like to send. If it's some kind of PC statistics like uptime, hardware etc. you would just use http query in client app to website script you've created (for instance mypage.com/?uptime=100&ram=2gb&hash=xxxx etc.)
Only the server (the computer which is accepting TCP requests) needs to have the port forwarded.
The common model is that you (the developer/producer of the service) host the server. Then customers (people who subscribe to your service) connect to your service using either an IP or a URL. If your service is behind a firewall (you have a router between your computer and your internet modem) then you will have to forward the port. You will probably also have to open the port in Window's firewall, but I expect you have done this already. In this model the customer does not have to do anything with their router (it is like using a web browser).
If you are making a product where your customers are hosting the service then they will have to deal with the port issues. In which case you could try ManagedUPnP like Albin Sunnanbo suggests or redirect them to one of the many sites explaining how to setup port forwarding.
Related
I have a server program and a client program. While developing the program I run the server and the client on the same machine for convenience. The server starts listening to incoming connections using these lines:
var listener = new TcpListener(IPAddress.Any, 7070);
listener.Start();
The client connects to the server using these lines (simplified):
var client = new TcpClient(AddressFamily.InterNetwork);
client.Connect(IPAddress.Loopback, 7070);
I use IPAddress.Loopback because I run the programs on the same machine. But, knowing that the server and the client won't be necessarily run on the same machine in the future, I changed it to my public IP from http://icanhazip.com (IPAddress.Parse(...)). Because of that the client was unable to connect to the server on the same machine with the exception No connection could be made because the target machine actively refused it <my public ip:7070>.
I tried disabling my firewall but it's still not working. Why is the server refusing the connection? Didn't I specifically tell it to listen to all interfaces with IPAddress.Any?
Why does that happen and how do I fix it?
Here's an answer built from my comments on the question, which are hopefully correct:
Your public IP is provided by your ISP and is actually the address of your router. The router does network address translation (NAT) for outgoing connections from computers within your local network. These requests look to the Internet like they're all coming from one IP, and your router sends responses to the right local computer based on an address translation table. This works for outgoing connections but not incoming connections.
If something tries to open a TCP connection from the Internet to your router, the router has no idea what local computer it might be trying to connect to unless you specifically configure it to forward that traffic to a particular computer on your local network. That's where port forwarding comes in. If you haven't configured port forwarding, the router just says, "sorry, I'm not handling incoming requests on port 7070."
Is your development machine behind a router?
Network traffic sent to you via your public IP address reaches your router on a given port via a specific networking protocol. Your router needs to know where to send this traffic internally on your network. Traffic is coming from the Internet to your machine, and your router either cannot or will not forward the traffic to your computer's machine.
You don't notice this in your day-to-day life thanks to the power of Network Address Translation (NAT) and Universal Plug and Play (UPnP). Glossing over some details here, Network Address Translation allows traffic headers to be modified to route traffic from your public IP to your actual machine's IP on the network. When incoming traffic attempts to open a port for connectivity on your network, the router needs to be configured to forward that traffic appropriately. Universal Plug and Play is a protocol supported on many modern routers to allow software and devices to seamlessly route traffic without the need to forward ports.
This leaves you with two options:
For development purposes, access your router and forward the desired port to your development machine
For a more robust application, especially if you're going to be running this on different machines or different networks, consider adding UPnP support to your application while also understanding that UPnP may not be supported or enabled by some users, in which case port forwarding is still necessary.
Many questions relating to port 80 being used have answers saying that there are many programs that use it as their default port. This post mentions some: Skype, IIS, Apache...
Since only one application can listen on any one port at a time - How can that be? And if the answer is that that's only their default port - how will an application know it has to send information to a different port? For example - if iis will listen on port 81 because Skype is listening on 80 - how will anyone requesting a web page know to send the request to theip:81 as opposed to theip:80?
My goal is to have a robust way of setting up a connection between programs, when any hard coded port might fail due to some application already listening on it. The port will only need to be used once in order to communicate what dynamic port will be used for the rest of the session. This is a problem for both network connections and for connecting several applications on the same computer.
Registering with IANA is not always possible, and won't even necessarily solve the problem - someone might still be listening on a registered port. And obviously the solution of "hope for no collisions" - just doesn't cut it.
(I do understand that a connection has two sockets (and a protocol) and therefore one socket can have multiple connections. My question is about listening on a socket in order to establish the connection.)
What I would expect, is there to exist some service on the OS (Windows) that I could register my application with, and receive all incoming traffic with some signature - even if it's simply some magic string. Or perhaps some port where multiple applications can listen concurrently - and all would get every incoming message. But I haven't found anything like that so far.
How can that be? Simply...it's not. Only one application will listen on each port. – Adriano Repetti
Right. When Skype listens on those ports before I start my web-server, the server fails. It took me a while to find out why.
Only one app can listen on a socket in a sane way. The OS allows multiple apps to listen on the same port if you specify special options but that's insane. Accepted connections are then dispatched to different applications in an unspecified (i.e. random) way.
IIS can run multiple web-apps on the same port because it opens the port once in kernel mode and dispatches connections to its worker processes.
I do not believe it is ever possible for multiple sockets to listen on the same (TCP) port. If you try to bind a socket to a port that is already open, you will get an error.
I believe Skype gets around the problem you describe by using their own servers as a rendezvous point. The simple explanation being:
Alice starts her client, connects to the central server, and informs it of what port she is listening on.
Bob starts his client and likewise informs the central server.
Now, Alice wants to connect to Bob, but doesn't know which port to send packets to.
Alice will then query the central server for Bob's port number.
With this information, a direct connection is then established with Bob using that port.
The logic can of course extend to learning the other party's IP address as well as even obtaining public keys.
Note that there's actually a bit more involved with most modern peer-to-peer applications, Skype being no exception. The problem being that most computers are now behind at least one NAT router. Getting two devices each behind their own router to connect to each other is known as NAT traversal - the most common technique having a central coordinating server instruct both clients to simultaneously connect to each other. For more information on this, I recommend Steve Gibson's Security Now!, episode #42
on the port forwarding setup page i just put a comma and add an other port to open. it wont allow you to set up an additional rule with listen port 80 but it will allow you to trigger multiple ports with that one listen port
For TCP, you can only have one application listening on a single port
at one time. Now if you had 2 network cards or created a virtual
interface, you could have one application listen on the first IP and
the second one on the second IP using the same port number.
For UDP (Multicasts), multiple applications can subscribe to the same
port.
one application listening on a single port that's the reason why ports exist. To allow multiple applications to share the network without conflicts.
But there are ways to do what you requested:
You could write a master process, which possesses the port and notifies slave processes using some separation logic.
On Linux and BSD you can set up remapping rules that redirect packets from the visible port to different ones(such as listener app), again by using some separation logic(e.g. redirect according to network origin etc.).
Note: For TCP, you multiple applications can listen on the same socket by using SO_REUSEADDR option before binding but what this does is redirect the incoming connection to only one of the listeners.
I'm not good in networking so for some people my question can look silly. I'm trying to connect to my ip camera from outside of my local network. I know that I need to do port forwarding. I read that ssh could be good idea. Imagine that my outside ip is 10.20.30.40 and my camera ip local ip is 1.2.3.4. When port forwarding will work I think that I will connect to camera using this address
"http://10.20.30.40/index1.htm". So all I need is port forwarding. Client can't do this on his own. I need to write an app to do this automatically. How can I do this using c# and am I going in right direction?
You can accomplish this on most home routers in their default configuration using UPnP - Universal Plug and Play.
This is a standardised mechanism for applications behind a NAT router to programmatically request ports to be forwarded to them.
See this question for details on accessing UPnP functionality from .NET. You need to persuade the router to forward TCP port 80 (standard port for HTTP) to your camera's LAN IP address.
Only way you can accomplish correctly configured port forwarding is through manual router configuration.
There is no way around it, for logical and obvious security reasons.
Ok, problem solved, when I turn upnp on my router on web pages didnt load. It turns out that camera had default port set to 80. I've changed it to 1001 and then set upnp enable on router and camera automatically forwarded port 1001 to it self. All I have to do programaticaly is set port on camera.
I use a basic application that enables me to send a file over a tcp connection over the internet to a different computer. The way I managed to do that was to configure the router at my house and office to port forward all incoming traffic from port X to the corresponding computer. I am in a new office now and things work different in here.
There is a main router where all the offices may connect to. I connect my router to that router in order to have my own private network. I still want to be able to use my small application that I created in order to sync the files from my home computer and office computer. The only problem is that I dont have access to the main router therefore I may not open any ports in order to make my program work. I am new to networking so it will be nice if someone can point me to the right direction of how can I solve this. I think I have to let the router know to send all the traffic from port x to my computer. Moreover there are several routers so I dont know if it is possible. I think it should be possible because I am able to connect to my office computer via log me in for example.
It sill be nice if I can still use TCP protocols instead of a p2p since I already have all the functionality.
It would be much easier to connect from your office to your home computer. In this scenario, you have to setup port forwarding on your personal router (which you have already done!). If you connect from your home to the office, you will need to configure every intermediate office router (which your boss probably won't like).
In order to connect to your home network, I would look into setting up DDNS through someone like DynDNS. This will allow you to connect to me.example.com from wherever and have it resolve to your home address even when it changes IP addresses.
I found a nice page that talks about this in here. I will work on it... I am not sure if it works with the tcp protocol.
I am thinking about writing a client server app using sockets in c#. My question is, if the server is behind a router and upnp is enabled, once the server starts listening does upnp automatically forward data incoming to that computer if it is destined for said port? I don't want the user to have to start forwarding ports, I am hoping my server app can be zero configuration.
Thanks in advance.
I worked on a uPNP tool a little while ago for a work application for file sharing across multiple sites.
I can confirm that during the port configuration via uPNP, that you do indeed specify which port and end point you would like to listen.
If uPNP reports back OK. All requests to the port will be forwarded to the passed end point.
I will find the class I made \ modified and give it as an example shortly....