4 have I connected to the Internet?
Now, with the help of the previous steps, the idea is simple:
(1) Check the status of all network interfaces on the computer. If they are all "Down", no network connection will be made.
(2) select one from the network interface in the "Up" status (note that Loopback is excluded), obtain the address of its gateway and DNS server, and Ping its gateway first, if you can Ping the server, Ping the DNS server to see if the server can be pinged.
If the gateway cannot be pinged, try another "Up" network interface. Repeat the process until all the "Up" network interfaces are detected.
Now the results are coming:
(1) As long as there is a network interface that can Ping the gateway, "the computer must have been connected to the local network ."
(2) As long as there is a network interface that can Ping the DNS, "the local network settings of the computer are correct ." Unless the DNS server itself fails (the probability of occurrence is not high) or your account is limited due to overdue payment, "This computer should be connected to the Internet ".
(3) Ping a "Well-Known" website such as "Baidu" to confirm that the website has been connected to the Internet. Ping general rules 100% to ensure that the website can be connected to the Internet.
Note:
Some websites do not respond to Ping data packets. For example, I found that Microsoft hosts do not care about Ping data packets, and the Ping operation on their hosts ends with "TimeOut.
Some friends can't help but say:
Isn't that your option? When I Ping An Internet host directly, do I know if I can access the Internet?
What should I do? There are too many reasons why you cannot access the Internet. If your network application can tell you more details:
Unable to connect to the Gateway. Please check your network settings
Unable to connect to the DNS server. The DNS service address "192.168.1.1" you specified may be incorrect, or the DNS server may be faulty ......
Is it more helpful for users to locate network problems?
In the example program, I wrote an IsOnline method to implement the aforementioned connection detection logic:
Static bool IsOnline ()
{
If (NetworkInterface. GetIsNetworkAvailable () = false)
Return false; // All NICs are "Dwon"
// Select the "Up" Nic and exclude the loopback interface
Var query = from nic in NetworkInterface. GetAllNetworkInterfaces ()
Where nic. OperationalStatus = OperationalStatus. Up &&
Nic. NetworkInterfaceType! = NetworkInterfaceType. Loopback
Select nic;
Foreach (var nic in query)
{
// Ping the gateway first
Ping pinger = new Ping ();
Bool GatewayReady = false;
Foreach (GatewayIPAddressInformation GatewayAddr in
Nic. GetIPProperties (). GatewayAddresses)
{
PingReply reply = pinger. Send (GatewayAddr. Address );
If (reply. Status = IPStatus. Success)
{
GatewayReady = true;
Break;
}
}
If (GatewayReady = false)
Continue; // All gateways are disconnected and no further tests are conducted to directly detect the next Nic.
// The Gateway is successfully pinged. You can Ping the DNS.
Foreach (IPAddress addr in nic. GetIPProperties (). DnsAddresses)
{
PingReply reply = pinger. Send (addr );
If (reply. Status = IPStatus. Success)
{
Return true;
}
}
}
Return false;
}
In the above Code, except for failing to Ping the real Internet of "Well-Known", all other work has been completed.
When the IsOnLine method returns "True", it indicates that the local network can Ping the DNS. Otherwise, "False" is returned. You can modify this method, let it return more detailed information based on the specific situation (for example, which Nic's gateway or DNS cannot be pinged ).
5. Let's get up in parallel!
Now let's look at "Cool.
Considering our "network connection" judgment logic, it is not difficult to find that these Ping operations can be executed in parallel. If multiple threads can be used to execute Ping operations at the same time, it can undoubtedly reduce the time to get the final conclusion "whether the Internet can be accessed.
We can convert the IsOneLine method to a multi-threaded version.
Use an independent thread to perform the Ping operation on each network interface. Wait until the thread of the Ping gateway finishes executing the Ping operation and decide whether to run the Ping DNS operation on a new thread Based on the execution result.
When a network card can be pinged to DNS, it should be notified to other threads to stop working, because the conclusion of "whether to access the Internet" has been drawn.
In fact, this involves a lot of complicated thread synchronization problems. We need to use multiple thread synchronization objects and how to cancel a thread execution in the middle 《. in the "application" section of NET 4.0 object-oriented programming, it took more than 100 pages to talk about multithreading. NET 4.0 base class library almost all the usage of thread synchronization objects, and strongly recommended. NET 4.0's "unified thread cancellation model" (see application article 16.5 "unified thread cancellation model") to cancel the execution of a thread in the middle.
Whether you can convert the IsOneLine method into a multi-threaded version is a touchstone for detecting whether you have mastered the multi-threaded technology.
Here, I would like to explain to you how to directly use TPL (task parallel Library) instead of threads.
We need to carefully analyze the processing logic of IsOnLine to see which parts can be parallel and how the cooperation between these parallel operations is.
Obviously, connection detection for multiple network interfaces can be performed in parallel, which is the first parallel task point.
Secondly, a network interface generally has only one gateway and does not need to be parallel. However, a network interface may have more than two DNS Service addresses. Obviously, this is the second task parallel point.
Third, when multiple parallel tasks run at the same time, any parallel task that obtains the final result of "Internet accessibility" needs to notify other tasks to stop execution in advance.
After the above considerations, the use of Parallel loop (Parallel. ForEach) rather than the Task object is a more reasonable choice. Parallel. ForEach can execute a loop in Parallel, and the loop can be aborted in advance through the ParallelLoopState object, and other working threads can be "notified.
The following IsOnLine version is implemented using the task parallel Library:
Static bool IsOnlineUseTPL ()
{
If (NetworkInterface. GetIsNetworkAvailable () = false)
Return false;
& N