|
// Copyright (c) 2010, Peter Smith
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// Redistributions of source code must retain the above copyright notice, this list
// of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright notice, this
// list of conditions and the following disclaimer in the documentation and/or
// other materials provided with the distribution.
//
// Neither the name of the Author nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
namespace SocketCommunications
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Net.NetworkInformation;
public static class SocketHelper
{
#region Fields
// Signals when the resolve has finished.
private static ManualResetEvent GetHostEntryFinished = new ManualResetEvent(false);
static IPHostEntry resolvedIPs;
private static List<IPAddressInfo> ipAddressesAvailable = null;
#endregion Fields
#region Methods
// Determine the Internet Protocol (IP) addresses for
// this host asynchronously.
private static void DoGetHostEntryAsync(string hostname)
{
GetHostEntryFinished.Reset();
//BroadCastSend ioContext = null;
IPStateObject ioContext = null;
try
{
ioContext = new IPStateObject();
ioContext.host = hostname;
Dns.BeginGetHostEntry(ioContext.host, new AsyncCallback(GetHostEntryCallback), ioContext);
// Wait here until the resolve completes (the callback calls .Set())
GetHostEntryFinished.WaitOne();
resolvedIPs = ioContext.ipHostEntry;
}
catch (Exception ex)
{
string error = ex.ToString();
}
foreach (IPAddress ip in ioContext.ipHostEntry.AddressList)
{
IPAddressInfo ipAddressInfo = new IPAddressInfo();
ipAddressInfo.IPAddress = ip;
ipAddressInfo.SubNetMask = null;
ipAddressInfo.BroadCastAddress = CalculateBroadCastAddress(ip, null);
ipAddressesAvailable.Add(ipAddressInfo);
}
}
// Record the IPs in the state object for later use.
private static void GetHostEntryCallback(IAsyncResult ar)
{
//BroadCastSend ioContext = (BroadCastSend)ar.AsyncState;
IPStateObject ioContext = (IPStateObject)ar.AsyncState;
//ioContext.IPs = Dns.EndGetHostEntry(ar);
ioContext.ipHostEntry = Dns.EndGetHostEntry(ar);
GetHostEntryFinished.Set();
}
private static void GetIPNetworkInformation(bool Include_IPV4, bool Include_IPV6)
{
foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces())
if (networkInterface.OperationalStatus == OperationalStatus.Up)
{
IPInterfaceProperties ipInterface = networkInterface.GetIPProperties();
foreach (UnicastIPAddressInformation unicastAddress in ipInterface.UnicastAddresses)
{
IPAddressInfo ipAddressInfo = new IPAddressInfo();
switch (unicastAddress.Address.AddressFamily)
{
case AddressFamily.InterNetwork:
if (Include_IPV4)
{
ipAddressInfo.IPAddress = unicastAddress.Address;
ipAddressInfo.SubNetMask = unicastAddress.IPv4Mask;
ipAddressInfo.BroadCastAddress = CalculateBroadCastAddress(unicastAddress.Address, unicastAddress.IPv4Mask);
}
break;
case AddressFamily.InterNetworkV6:
if (Include_IPV6)
{
ipAddressInfo.IPAddress = unicastAddress.Address;
ipAddressInfo.SubNetMask = null;
ipAddressInfo.BroadCastAddress = null;
}
break;
default:
break;
}
if (ipAddressInfo.IPAddress != null)
ipAddressesAvailable.Add(ipAddressInfo);
}
}
}
public static IPAddress CalculateBroadCastAddress(IPAddress ipAddress, IPAddress ipNetMask)
{
if (ipNetMask == null)
{
return CalculateClassABC_BroadCastAddress(ipAddress);
}
string[] strCurrentIP = ipAddress.ToString().Split('.');
string[] strIPNetMask = ipNetMask.ToString().Split('.');
int[] arBroadCast = new int[4];
for (int i = 0; i < 4; i++)
{
int nrBCOct = int.Parse(strCurrentIP[i]) | (int.Parse(strIPNetMask[i]) ^ 255);
arBroadCast[i] = nrBCOct;
}
return IPAddress.Parse(arBroadCast[0] + "." + arBroadCast[1] + "." + arBroadCast[2] + "." + arBroadCast[3]);
}
private static IPAddress CalculateClassABC_BroadCastAddress(IPAddress ipAddress)
{
string[] octets = ipAddress.ToString().Split('.');
byte b = byte.Parse(octets[0]);
//Class C or above
if (b >= 192)
return IPAddress.Parse(octets[0] + "." + octets[1] + "." + octets[2] + ".255");
//Class B
if (b >= 128)
return IPAddress.Parse(octets[0] + "." + octets[1] + ".255.255");
//Class A (== 0)
return IPAddress.Parse(octets[0] + ".255.255.255");
}
public static List<IPAddressInfo> IPAddressesAvailable
{
get
{
if (ipAddressesAvailable == null)
{
//GetIPNetworkInformation is not implemented completely on Mono therefore this
//workaround. This will not figure out broadcast based upon subnet
Type t = Type.GetType("Mono.Runtime");
ipAddressesAvailable = new List<IPAddressInfo>();
if (t != null)
{
DoGetHostEntryAsync(Dns.GetHostName());
}
else
{
GetIPNetworkInformation(true, false);
}
}
return ipAddressesAvailable;
}
}
#endregion Methods
#region Nested Types
public class IPStateObject
{
#region Fields
public string host;
public IPHostEntry ipHostEntry;
#endregion Fields
}
#endregion Nested Types
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.