I know about the IsNetworkAlive function from the Windows API but IsNetworkAlive returns false until there's any network activity.
That is, if you start your computer and test connectivity it will return false. If you then ping another computer (or recieve a ping or any network activity from another computer) then it will start returning true.
Is there any alternative or does anyone know a workaround for this?
Things I've tried so far:
Ping to the local host (no go as there isn't really any network activity)
Ping to the local address (the same as before)
Note: I know there's another question very similar to this one, but my problem here is with IsNetworkAlive behaviour
The WinInet functions should meet your needs. Of particular interest is the InternetGetConnectedState function.
Maybe this is what you want: Check network connection status using C#.net?
(It use InternetGetConnectedState WinInet function)
Consider using
NetworkChange Class
The Connection Monitor Application Block
Related
Sorry for asking such a mundane question, but I'm suddenly curious. If I open the network connections dialog on my Windows machine, it shows me a cute little picture of my computer connecting to a router and then to a globe (labeled Internet). What is Windows trying to connect to in order for it to decide that the computer has Internet connectivity? I assume there is no IP4 address for 'The Internet', so where is it going? Is it just sending a ping to an address back at the Microsoft home office? If that address were to disappear, would my window's machine suddenly decide that it no longer has a route to the Internet? Would Windows boxes that were 'close' to that address incorrectly report that they could get to the Internet when they couldn't.
I'll stop now before this gets too silly. But seriously, what criteria does a Windows box use to determine that it has Internet connectivity? I'm assuming that Linux and iOS systems have an equivalent feature. Do they use the same criteria?
The general IP address that is used for 'the internet' is 8.8.8.8 - or Google.com.
If you can ping it, and get a web page from it, then there's a pretty good chance you can get to at least some of the internet.
But for specifically Windows - Network Connectivity Status Indicator - it uses a different domain: dns.msftncsi.com
It will (unless disabled by GPO):
resolve the name, and verify it has the 'right' IP (131.107.255.255
fd3e:4f5a:5b81::1 )
Perform a HTTP get to this address and check it gets a result. NCSI
Presumably if different responses are retrieved, then it can tell if it has a wi-fi login or similar.
Your intuitions seem correct. I am not on a Windows machine but you could find out by firing netstat and then connecting.
If I was programming this I'd make Ping, TCP and HTTP requests. Some devices are connected through proxies such as firewalls, captive portals and others. the only way to be sure is to send something and receive a reply.
My Android device for example can detect captive portals. It probably does that by trying to HTTP connect somewhere.
why the NetworkInterface.GetIsNetworkAvailable() method always returns true,when i debug it on my windows phone 7 device?not emulator,is it sure that "NetworkInterface.NetworkInterfaceType==NetworkInterface.None" means a device does't get network access?how can i detect whether a device connected a network that has intenert access? i tried this link,Zune-Detection-and-Network-Awareness,but the NetworkInterface.GetIsNetworkAvailable() method always returns true,which stumbled me a lot.Thanks for your help.
Read the documentation for the method. Here is what MSDN has to say:
A network connection is considered to be available if any network
interface is marked "up" and is not a loopback or tunnel interface.
There are many cases in which a device or computer is not connected to
a useful network but is still considered available and
GetIsNetworkAvailable will return true. For example, if the device
running the application is connected to a wireless network that
requires a proxy, but the proxy is not set, GetIsNetworkAvailable will
return true. Another example of when GetIsNetworkAvailable will return
true is if the application is running on a computer that is connected
to a hub or router where the hub or router has lost the upstream
connection.
Generally, you could say that this method is generally prone to errors. I would recommend taking the approach of failed requests - have a couple of URLs to test against and check if HTTP/DNS resolve requests go through. If some of them pass - there is a connection. If all fail - chances are you are not connected.
Here is a sample.
I implement asynchronous download to retrieve remote file and store it in IsolatedStorage in order to use it when out of the network.
Everything works great when network is up. However when out of network, I noticed that async donwload may take up to 2 minutes before to fire my MessageBox (which say that connection to server has failed).
Question:
Is there any way to define a timeout ? Let's say that if my application does not receive any answer for X seconds then stop the Async Download and call a method.
Maybe a timeout is not the best pratices. In this case could you give me suggestion ?
I do not want my user wait for 15 seconds max.
PS: my application is suppose to run on wifi only, so I consider that 'network speed' is optimal.
Thx for your help
What I would recommend doing is check the network type first via NetworkInterface. If NetworkInterfaceType is Wireless80211, you have a wireless connection (Wi-Fi). The returned connection can be None in case there is no available way to connect - so you won't even have to start the download if there is no accessible network.
Answering your question, if you are using WebClient, you can't define a timeout. However, you can call instance.CancelAsync(). For a HttpWebRequest you can call instance.Abort().
alt text http://img440.imageshack.us/img440/6950/problemyd1.png
(The curly lines with dots represent a network route.)
Having a process called "foo.exe", is there a way to forward everything it communicates over TCP/IP to a forwarding proxy located elsewhere? This forwarding should not reflect to other processes.
Another question: if there are multiple network adapters, is it possible to force a process to use one specific adapter.
Since in this example the targethost.com is known, I could just edit "system32\drivers\etc\hosts" to map targethost.com's IP to localhost, where on port 8765 would be the first forwarder waiting for an incoming connection and pass everything forward to proxy.foo.com. I was wondering if there's a more elegant way of doing this.
This is not for malware, I'm doing some network testing with my complex home network. Thank you for warning us.
Some free software for this would be perfect, alternatively a code idea (native or .net). Thank you very much.
It's not too hard if you make your own computer a firewall, then your app connects to a port on your own computer, and that port is forwarded to both the original destination and logged or forwarded on to your spying computer.
Alternatively you can make your other computer the firwall and have it log/forward the info.
Finally you could use a sniffer.
SocksCap will probably do the job (if you're OK with establishing a SOCKS proxy at proxy.foo.com).
You could hook into the TCP stack, for example, by using the Windows Filtering Platform or its predecessors, or you could substitute the network libraries/calls of that particular process.
Consider the following setup:
A windows PC with a LAN interface and a WiFi interface (the standard for any new laptop). Each of the interfaces might be connected or disconnected from a network. I need a way to determine which one of the adapters is the one connected to the internet - specifically, in case they are both connected to different networks, one with connection to the internet and one without.
My current solution involves using IPHelper's "GetBestInterface" function and supplying it with the IP address "0.0.0.0".
Do you have any other solutions you might suggest to this problem?
Following some of the answers, let me elaborate:
I need this because I have a product that has to choose which adapter to bind to. I have no way of controlling the setup of the network or the host where the product will run and so I need a solution that is as robust as possible, with as few assumptions as possible.
I need to do this in code, since this is part of a product.
#Chris Upchurch: This makes me dependent on google.com being up (usually not a problem) and on any personal firewall that might be installed to allow pinging.
#Till: Like Steve Moon said, relying on the adapter's address is kind of risky because you make a lot of assumptions on the internal network setup.
#Steve Moon: Looking at the routing table sounds like a good idea, but instead of applying the routing logic myself, I am trying to use "GetBestInterface" as described above. I believe what it should do is exactly what you outlined in your answer, but I am not really sure. The reason I'm reluctant to implement my own "routing logic" is that there's a better chance that I'll get it wrong than if I use a library/API written and tested by more "hard-core" network people.
Technically, there is no "connected to the Internet". The real question is, which interface is routeable to a desired address. Right now, you're querying for the "default route" - the one that applies if no specific route to destination exists. But, you're ignoring any specific routes.
Fortunately, for 99.9% of home users, that'll do the trick. They're not likely to have much of a routing table, and GetBestInterface will automatically prefer wired over wireless - so you should be good. Throw in an override option for the .1% of cases you screw up, and call it a day.
But, for corporate use, you should be using GetBestInterface for a specific destination - otherwise, you'll have issues if someone is on the same LAN as your destination (which means you should take the "internal" interface, not the "external") or has a specific route to your destination (my internal network could peer with your destination's network, for instance).
Then again, I'm not sure what you plan to do with this adapter "connected to the Internet", so it might not be a big deal.
Apparently, in Vista there are new interfaces that enable querying for internet connectivity and more. Take a look at the NLM Interfaces and specifically at INetworkConnection - you can specifically query if the network connection has internet connectivity using the GetConnectivity method.
See also: Network Awareness on Windows Vista
Unfortunately, this is only available on Vista, so for XP I'd have to keep my original heuristic.
I'd look at the routing table. Whichever NIC has an 0.0.0.0 route AND is enabled AND has the lowest metric, is the nic that's currently sending packets to the internet.
So in my case, the top one is the 'internet nic'.
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 10.0.0.10 10.0.0.51 20
0.0.0.0 0.0.0.0 10.0.0.10 10.0.0.50 25
(much other stuff deleted)
Another alternative is to ping or GetBestInterface 4.2.2.2 - this is an old and venerable DNS server, currently held by GTEI; formerly by Sprint if I remember right.
Start > Run > cmd.exe (this works in XP and Vista): ipconfig /all
This displays all info about the interfaces in your computer. The "public" facing interface should have a public IP address. For starters, it should not be 192.168.x.x or 10.x.x.x :)
running traceroute to some public site will show you. Of course, there may be more than one interface that would get you there.
Look at the routing table? Generally, unless you're routing between the networks in windows (which is possible, but unusual for a client computer these days) the interface that holds the default route is going to have the Internet connection.
Your question didn't detail why or what you're doing this with so I can't provide any specifics. The command line tool "route" may be of some help, but there are probably libraries for whatever programming language you're using to look at the routing table.
You can't rely on the IP address of the interface (e.g., assuming an RFC-1918 address [192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8] isn't the internet) since most sites have some kind of NATed firewall or proxy setup and the "internet" interface is really on a "private" lan that gets you out to the Internet.
UPDATE: Based on your further information, it sounds like you have a decent solution. I'm not so sure about the choice of 0.0.0.0 since that's a boundary case for IP address -- might be OK on your particular mix of platform/language. Sounds (from the API description) like you could just specify an address, so why not some address known to be on the Internet, e.g. the IP address of your web site, or something more random like 65.66.67.68? Just make sure not to pick one of the rfc-1918 addresses, or the localhost range (127.0.0.0/8), or multicast, any other reserved range, and any address that resolves to a .mil or .gov (while it doesn't sound like getbestinterface sends any traffic, it would suck to find out by having the feds break your door down... :)
Looking at the network point of view, either could be routing to the "internet" at any time. If things like spanning tree protocol are enabled on a switch then you may find that what may have been the routing card to begin with may not be anymore.
Ping google.com though each NIC.