client/server chat program in C#/winforms IP address issue - c#

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.

Related

c# Socket.RemoteEndPoint shows different port that I'm using to connect

I've developed a basic console application that will work as server-client. My general workflow will be like, Server starts clients connect to server and once a client send something the server will receive it and send it to ALL clients. Currently I can do this with my codes but my question is when I send back I've tested Socket.RemoteEndPoint and I saw ports like 65xxx. Like my first client had 65020, second 65021 and so go on. I wonder why this happen since I connect with using 9001 port and listen to 9001 port on my computer. I've done a little bit research but couldn't find a solution to my question. Why do I get these port numbers when I use Socket.RemoteEndPoint? It's okay for me since I don't use firewall or anything while I'm testing to even if the clients connects from another ports it's fine by me as long as its works but what if I have a firewall and I open ONLY 9001 port? Will my client-server based programs work then?
So far as the server/firewall on that machine is concerned, what normally matters is the server port. You wouldn't normally apply any filtering based on the client's port, which as I said in a comment, will normally be an ephemeral port. Under most circumstances, client code will make no effort to specify the local port or IP address and will let the OS pick appropriate values.
The Socket class's LocalEndPoint and RemoteEndPoint use "local" and "remote" to mean "from the perspective of the machine on which this code is running", not "who initiated the connection vs who was connected to".
So on the server, LocalEndPoint will give you information about the server end of the connection and RemoteEndPoint will give you information about the client end of the connection. Irrespective of who initiated the connection.

Connecting to myself using .NET sockets

I'm creating a server client application. I have been able to connect to applications on the same network. For example I can connect to 10.0.0.3 and 10.0.0.4.
Now I have been trying to connect to my external IP and I recieve:
System.Net.Sockets.SocketException (0x80004005). No connection could be made because the target machine actively refused it.
listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
write = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
end = new IPEndPoint(IPAddress.Parse(IP), 3212);
write.Connect(end);
Is this a problem with my code or with my router settings? Or is it that you can't connect to yourself... however that wouldn't make sense considering I can connect to 127.0.0.1.
This is a common loopback error, because you're router gets confused when doing Internet NAT redirections. Your external IP is assigned to your modem/router...not your computer, remember that your router could be handling traffic for more than one device inside the network under one single external IP then it uses NAT to redirect traffic to specific local connected devices. One example is, your home network with 2 computers, one printer and 2 mobile devices, all of them connected to your home network via wi-fi, all of them will have a local IP address assigned possible via DHCP, however, the external IP address is the same for all local devices because the external IP address is assigned to your router.
When connecting to local network devices ALWAYS use a local IP address instead of the external one
Edit
I wanted to keep this answer as simple as possible but Scott's comment made me re-think that it is always useful to add details that can help the community out there.
Basically, you can actually set up Port Forwarding which allows your router to redirect incoming traffic received in a specific port to a designated device in your local network. This will make your device accessible from outside your network on that specific port and you can easily take advantage of this to connect to sockets from inside your local network using your external IP address. The flip side is that not all routers/modems support Port Forwarding, so you will have to refer to your modem's manual and check if it's supported or not.
But, if you want to set it up solely for the reason that you want to connect devices from your local network using the external IP, I would recommend you NOT to do it and use the internal IP address, you don't really want to go through the security risks that are involved in exposing your local devices to the internet. You can easily set up strict firewall rules to outsiders and a more relaxed security in your local network.
For my socket application I used port number from 10000, secondly I have created Windows Firewall Rule on socket server computer, which allows your external client to connect to the socket server. you can specify number of individual ip address or a range with a port number 10000. From Start -> All Programs -> Windows Firewall with Advance Security. Follow the prompts set the rule for your client IP. Good luck
I presume the IP address you want to connect to is not 127.0.0.1, but your own IP address as used on the internet (e.g. 80.110.140.30)? You can't do that. Try copy-and-pasting that same IP address in your browser, for example, and you'll see it either does not connect or redirects to your router.
From your own network, the only way to connect to yourself is through the loopback device (localhost or 127.0.0.1).

Unable to connect to local machine IP address using internet IP address

I've spent the last month writing a multiplayer game. I have only been testing it on one machine, using 127.0.01:9051 as the IPEndPoint.
I changed the IP address to my WAN IP, configured port forwarding on my router, configured my software firewall etc... But, it doesn't connect.
I have checked if the port is open using this site. Result: the port is really open.
Also, when I check the port from that website, my server receives packets just fine; however, when I connect from my own machine... it doesn't receive anything.
I've broken everything down to the basics to make sure it wasn't a problem with my code.
This basic code does not work:
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("XXX.XXX.XXX.XXX"), 9051);
TcpClient client = new TcpClient();
client.Connect(iep);
Any ideas are much appreciated.
If you are attempting to connect to the IP that is Forwarded (outsideIP) to the same machine (insideIP), it won't work. There are very few enterprise firewalls and no consumer devices (I know of) that will route a packet from the inside out and translate it back in.
[Internet] -- outsideIP[Router/Firewall]insideIP1 -- insideIP2[Computer]
In this case, packets from insideIP(X) will not be able to connect to outsideIP.
Try to see if you can telnet to your wan IP on port 9051. Routers don't really like it when you connect to their wan IP from within the network itself.
You could use Dyndns or some other service for the outside world to connect to your server and put the same name into your host file that resolves to 127.0.0.1 so that you can connect internally.
Is your client and your server (both the same machine in your failing test) using the same endpoint ip/port? You can only bind a port once at a time. Try using two ports one for server in one for server out (clinet in). That way they will not clash. Use Telnet to check you can connect to the IP/Ports you are using and Netstat to check they are not in use already.

Add a NAT UPnP mapping on a complex network using C#

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.)

GetExtendedUdpTable and Remote Ip Address

I've got some c# code that is mapping processes to ip addresses, I'm basically trying to write some software that will look at a process and give me the ip address so that I can write a monitor that will allow friends to find be in games.
When running my application though it detects that a game process has a UDP connection but I can't seem to get the ip address.
I've run a packetsniffer and 78.111.229.123:32000 shows up on the router/gateway but it's not showing in my application.
Any ideas to get me up and running?
How are you setting up the socket in the game application? Can you post an example of your socket setup code?
Are you using the wildcard address and port when creating the socket? I'm guessing that if your game application doesn't bind to a specific IP address and port explicitly that may be the source of your problem.
Another question: are you trying to detect the local IP address, remote IP address or both?
If you're trying to detect the remote IP address this may be impossible unless the game application is using what's known as connected UDP sockets. This is where the client application calls connect on the UDP socket to create an association between the local and remote sockets in the underlying OS. This has certain advantages and drawbacks as listed in the above link.
Edit
Take a look at this SO post: PID from socket number on Windows?
This pretty much confirms what I thought - unless the game is using connected UDP sockets then the only way you'll be able to get the remote address is via packet sniffing.
Start up the game and run netstat -ap UDP - if you see that there aren't any remote addresses listed then that would confirm the above suspicion.

Categories

Resources