. Net 4.0 getting started with network development -- I am in the center of "network" (lower)
The previous article ". Net 4.0 getting started with network development-I am in the" network "center (I)"
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 applicationProgramMore detailed information about users:
- 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:
Synchronous version network detection method 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 ; // No gateway connection is available. If you do not perform the next test, you can directly detect the next Nic.
// The gateway is successfully pinged. You can ping DNS.
Foreach (IPaddress ADDR In Nic. getipproperties (). dnsaddresses)
{
Pingreply reply = Pinger. Send (ADDR );
If (Reply. Status = Ipstatus. Success)
{
Return True ;
}
}
}
Return False ;
}
AboveCodeIn addition to failing to ping a "well-known" real Internet, 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:
Concurrent Version connection Detection Method Static Bool Isonlineusetpl ()
{
If (Networkinterface. getisnetworkavailable () = False )
Return False ;
// Select All activated NICs
VaR Query = From Nic In Networkinterface. getallnetworkinterfaces ()
Where Nic. operationalstatus = Operationalstatus. Up &&
Nic. networkinterfacetype ! = Networkinterfacetype. loopback
Select Nic;
Int Nicready = 0 ; // This value is greater than 0 when the DNS of one Nic is available.
// The following defines parallel tasks for each network interface
Action < Networkinterface, parallelloopstate > Pingnetworkinterface =
(NIC, outstate) =>
{
Ping Pinger = New Ping (); // Ping Gateway
Bool Gatewayready = False ;
Foreach (Gatewayipaddressinformation gatewayaddr In
Nic. getipproperties (). gatewayaddresses)
{
If (Outstate. isstopped) // The Ping cycle of other NICs has been aborted.
Return ;
Pingreply reply = Pinger. Send (gatewayaddr. Address );
If (Reply. Status = Ipstatus. Success)
{
Gatewayready = True ;
Break ;
}
}
If (Gatewayready ! = True ) // The gateway cannot be pinged. You do not need to ping the DNS.
Return ; // End the ping of this Nic
Else // The gateway can ping all DNS addresses in parallel.
{
Parallel. foreach (NIC. getipproperties (). dnsaddresses,
(Dnsaddr, innerstate) =>
{
// Other Ping cycles (for this Nic or for other NICS) have been aborted
If (Innerstate. isstopped | Outstate. isstopped)
Return ;
Ping pinger2 = New Ping ();
Pingreply reply = Pinger2.send (dnsaddr );
If (Reply. Status = Ipstatus. Success) // Ping successful
{
// Indicates that this Nic DNS is reachable
Interlocked. increment (RefNicready );
// No need to perform subsequent loop operations of this parallel Loop
Innerstate. Stop ();
Outstate. Stop (); // The upper-layer parallel loop can also be aborted.
Return ;
}
}
);
}
}; // End of parallel task definition
// Execute parallel Tasks
Parallel. foreach (Query, pingnetworkinterface );
Return Nicready > 0 ;
}
The above code is relatively long and uses some complex programming features, such as "LINQ query", "Lambda" expressions, and parallel Parallel Loops. Please read the following sections in. Net 4.0 object-oriented programming to clear the knowledge barriers. Then, read the comments in the Code and debug the code in Visual Studio to understand the code:
- Section 8.4 anonymous methods and lambda expressions
- Section 11.5 "skills in writing LINQ Query expressions"
- Section 17.2.3 "implement atomic operations-interlocked"
- Section 19.3.3 writing parallel code using parallel
- Section 19.3.9 parallel task Cancellation
If you want to use the parallel version of isonlinetpl for programs with visual interfaces, we recommend that you create a new background thread to execute this method, then, use the method described in Chapter 18th cross-thread access visualization control to "push" the result to the UI thread to update the visual interface (for example, switching to display images like Windows ).
In addition ,. net base class library has a networkchange sealing class. When the IP address of the user's computer changes (including the user's manual changes, or the user has disabled the wireless function and other indirect reasons) it can trigger a networkaddresschanged event. In this event, you can call the isonlinetpl method to re-detect whether the network is reachable.
6 Summary
Because my network environment is relatively simple, I cannot test whether the isonlinetpl method works normally in a variety of network environments. In addition, this method only detects whether the DNS is "accessible, no real "Internet host" is pinged, and some network hosts may ignore the packets sent by the "ping" operation. Therefore, the isonlinetpl return false does not necessarily mean that the network is inaccessible. You can improve your code or design a new and better implementation solution.
This article is just a reference. If you have any mistakes, please post them back and point out. Thank you!
========================================================
Click to download the example source code associated with this article
Notice:
InArticleThe main character of. NET network development-socket will be officially launched!