Converting IPAddress[] to string - c#

I've got a server application which I'm trying to automatically set the IP address to, taken from the machine's dynamically allocated IP address. So far I've got this to get the IPv4 but it's returned as type IPAddress[] which I have some trouble converting to a string[] so my HttpListener can use it. Any hint to how I can convert it? Or am I going about this the wrong way?
This is what I'm using to get the IP address:
class Program
{
static void Main(string[] args)
{
string name = (args.Length < 1) ? Dns.GetHostName() : args[0];
try
{
IPAddress[] addrs = Array.FindAll(Dns.GetHostEntry(string.Empty).AddressList,
a => a.AddressFamily == AddressFamily.InterNetwork);
Console.WriteLine("Your IP address is: ");
foreach (IPAddress addr in addrs)
Console.WriteLine("{0} {1}", name, addr);
//Here I'm trying to convert the IPAddress[] into a string[] to use in my listener
string str = addrs.ToString();
string[] ipString = { str };
Response.Listener(ipString);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
//current way of setting the IP address - not optimal
string[] ipstring = new string[1] {"10.10.180.11:8080"};
Response.Listener(ipstring);
}
}
And the listener for good times sake:
public static void Listener(string[] prefixes)
{
if (!HttpListener.IsSupported)
{
Console.WriteLine("Windows XP SP2 or Server 2003 is required to use the HttpListener class.");
return;
}
// URI prefixes are required,
// for example "http://contoso.com:8080/index/".
if (prefixes == null || prefixes.Length == 0)
throw new ArgumentException("prefixes");
// Create a listener.
HttpListener listener = new HttpListener();
// Add the prefixes.
foreach (string s in prefixes)
{
listener.Prefixes.Add("http://" + s + "/");
}
listener.Start();

This should do the trick.
string[] ips = addresses.Select(ip => ip.ToString()).ToArray();
Make sure you have a using statement for System.Linq

You are trying to convert an IPAdress's array like one IPAdress.
You can use LINQ to convert each IPAdress, then you can make the String's array :
String[] strAddrs = (from cad in addrs select cad.ToString()).ToArray();
Don't forget : using System.Linq;

If you have an IPAddress object, you can get the string representation like this:
v4:
validIP4.MapToIPv4().ToString();
v6:
validIP4.MapToIPv6().ToString();

Related

Getting underlying IP used in database connection

I'm trying to see how pooled database connections are affecting the load balancing of commands between a fleet of read only MySQL database replicas. The data source in the connection string is a DNS entry that has several entries which are served to the client in a round robin fashion.
Is it possible to take the database connection object and extract the IP address that the connection is using to connect?
Update
In this code example:
MySql.Data.MySqlClient.MySqlConnection _mySQL = new MySql.Data.MySqlClient.MySqlConnection(_AuroraClusterEndPoint);
Update #2
My question is more of how to determine what IP an active connection is using and not really how to evenly distribute traffic.
Pseudo Code:
MySql.Data.MySqlClient.MySqlConnection _mySQL = new MySql.Data.MySqlClient.MySqlConnection(_AuroraClusterEndPoint);
_mySQL.Open();
Console.WriteLine(_mySQL.ConnectionInfo.IPAddress); //This is the unknown part
_mySQL.Close();
How would I take _mySQL and extract the IP address it is using?
Yes and no,
Don't store the dns hostname in your connection string. Build the connection string on the fly, (anyway you can or want to store the information).
When building the connection string in code lookup the dns alias/host name to get it's ip addresses (should only return 1 ipv4 address)
IPAddress[] ipv4Addresses = Array.FindAll(
Dns.GetHostEntry("hostnamehere").AddressList,
a => a.AddressFamily == AddressFamily.InterNetwork);
Test it and debug if you get multiple addresses.
Once you get the IP you now know what IP address the round robin gave the request, you can log it, then build your connection string with the IP address instead of the host name.
Here's a rough and dirty example I wrote in 5 minutes:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
string ipAddress;
var newConnectionString = SwapConnectionStringDNSWithIP("Server=google.com;Database=myDataBase;Uid=myUsername;Pwd=myPassword;", out ipAddress);
Console.WriteLine(ipAddress);
Console.WriteLine(newConnectionString);
Console.ReadKey(true);
}
public static string SwapConnectionStringDNSWithIP(string connectionString, out string ipAddress)
{
ipAddress = null;
if (string.IsNullOrEmpty(connectionString))
return null;
var dict = new Dictionary<string, string>();
var pParts = connectionString.Split(';');
foreach (var part in pParts)
{
if (part.IndexOf('=') == -1)
break;
var sParts = part.Split('=');
if (sParts.Length != 2)
break;
string key = sParts[0].ToLower().Trim();
string value = sParts[1];
if (!dict.ContainsKey(key))
{
dict.Add(key, value);
}
}
var server = dict.ContainsKey("server") ? dict["server"] : null;
if (server == null)
return null;
var ret = Dns.GetHostEntry(server);
var addresses = ret.AddressList.Select(a => a.GetAddressBytes()).ToArray();
if (addresses != null && addresses.Length > 0)
{
ipAddress = string.Join(".", addresses[0]);
dict["server"] = ipAddress;
var newConnectionString = string.Join(string.Empty, dict.Keys.Select(k => k + "=" + dict[k] + ";").ToArray());
return newConnectionString;
}
return null;
}
}
}

How to Get system IP (IPv4) address and convert to string using C# asp.net

On my web application I am using the following function to get System IP
Function
public void SetHostid()
{
try
{
string ip = "";
string strHostName = "";
strHostName = System.Net.Dns.GetHostName();
IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(strHostName);
IPAddress[] addr = ipEntry.AddressList;
ip = addr[1].MapToIPv4().ToString();
HostId = ip;
HttpContext.Current.Session["Hostid"] = HostId;
}
catch (Exception ex)
{
Error_ManagerClass em = new Error_ManagerClass();
em.WriteError(ex);
}
}
It works perfectly because the IP is on the 1 postion of the variable addr (addr[ 1]).
And the problem comes when I try to run the same solution from a different system. function throws an error while trynig to convert IP to string( ip = addr[1].MapToIPv4().ToString(); ) because IP is not in the position number 1.
how can I change the function to work on every computer ??
If you want to get IPv4 only use this code:
var addr = ipEntry.AddressList.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork);
var firstInList = addr.First(); // get first
But you should consider which IP to chose when there are several IP addresses in system.

Get value from a list and work with it

I am trying to build an application sends emails by socks, messages will be sent per message if the first message is sent through a socks, the second should use a different socks, what I do in my application if I as I Recuper the information from a txt file and I add to list :
try
{
SmtpServer oServer = new SmtpServer("");
var list = new List<string>();
var input = File.ReadAllText(#"C:\New folder\SendMail6\socks-list.txt");
var r = new Regex(#"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d{1,5})");
foreach (Match match in r.Matches(input))
{
string ip = match.Groups[1].Value;
string port = match.Groups[2].Value;
list.Add(ip);
list.Add(port);
}
foreach (string ip in list)
{
}
}
catch(Exception)
{
}
what I want that
oServer.SocksProxyServer = "37.187.118.174";
oServer.SocksProxyPort = 14115;
takes the values from the list I completed by ip values and port, and
if the first mail is sent by an ip the second mail is use another ip in list dont send tow email which follow by same ip
Thanks
You need to create a class for IP and Port
public class IpAndPort
{
public string IpAddress { get; set; }
public string Port { get; set; }
}
Now use ConcurrentBag
using System.Collections.Concurrent;
//------
var ips = new ConcurrentBag<IpAndPort>();
var input = File.ReadAllText(#"C:\New folder\SendMail6\socks-list.txt");
var r = new Regex(#"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d{1,5})");
foreach (Match match in r.Matches(input))
{
string ip = match.Groups[1].Value;
string port = match.Groups[2].Value;
if(ips.Any(x => x.IpAddress.Trim() == ip.Trim()))
continue;
ips.Add(new IpAndPort { IpAddress = ip, Port = port});
}
Now send message by taking values from ConcurrentBag
while (!ips.IsEmpty)
{
IpAndPort ipAndPort;
if (!ips.TryTake(out ipAndPort)) continue;
try
{
//code here to send message using below IP and Port
var ip = ipAndPort.IpAddress;
var port = ipAndPort.Port;
/----
oServer = new SmtpServer("");
oServer.SocksProxyServer = ip;
oServer.SocksProxyPort = port;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

How to get IPv4 and IPv6 address of local machine?

I am developing a windows application and I need to find the IPv4 and IPv6 address of local machine. OS can be XP or Windows 7.
I got a solution for getting MAC address like,
string GetMACAddress()
{
var macAddr =
(
from nic in NetworkInterface.GetAllNetworkInterfaces()
where nic.OperationalStatus == OperationalStatus.Up
select nic.GetPhysicalAddress().ToString()
).FirstOrDefault();
return macAddr.ToString();
}
This is working in all OS.
What is the correct way to get IPv4 and IPv6 address that work on XP and WINDOWS 7?
string strHostName = System.Net.Dns.GetHostName();;
IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(strHostName);
IPAddress[] addr = ipEntry.AddressList;
Console.WriteLine(addr[addr.Length-1].ToString());
if (addr[0].AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
{
Console.WriteLine(addr[0].ToString()); //ipv6
}
To get all IP4 and IP6 address, here is my preferred solution. Note that it also filters the loopback IP addresses like 127.0.0.1 or ::1
public static IEnumerable<IPAddress> GetIpAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
return (from ip in host.AddressList where !IPAddress.IsLoopback(ip) select ip).ToList();
}
Here's my method for getting all the IPv4 addresses only.
/// <summary>
/// Gets/Sets the IPAddress(s) of the computer which the client is running on.
/// If this isn't set then all IPAddresses which could be enumerated will be sent as
/// a comma separated list.
/// </summary>
public string IPAddress
{
set
{
_IPAddress = value;
}
get
{
string retVal = _IPAddress;
// If IPAddress isn't explicitly set then we enumerate all IP's on this machine.
if (_IPAddress == null)
{
// TODO: Only return ipaddresses that are for Ethernet Adapters
String strHostName = Dns.GetHostName();
IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
IPAddress[] addr = ipEntry.AddressList;
List<string> validAddresses = new List<string>();
// Loops through the addresses and creates a list of valid ones.
for (int i = 0; i < addr.Length; i++)
{
string currAddr = addr[i].ToString();
if( IsValidIP( currAddr ) ) {
validAddresses.Add( currAddr );
}
}
for(int i=0; i<validAddresses.Count; i++)
{
retVal += validAddresses[i];
if (i < validAddresses.Count - 1)
{
retVal += ",";
}
}
if (String.IsNullOrEmpty(retVal))
{
retVal = String.Empty;
}
}
return retVal;
}
}

Get IPv4 addresses from Dns.GetHostEntry()

I've got some code here that works great on IPv4 machines, but on our build server (an IPv6) it fails. In a nutshell:
IPHostEntry ipHostEntry = Dns.GetHostEntry(string.Empty);
The documentation for GetHostEntry says that passing in string.Empty will get you the IPv4 address of the localhost. This is what I want. The problem is that it's returning the string "::1:" on our IPv6 machine, which I believe is the IPv6 address.
Pinging the machine from any other IPv4 machine gives a good IPv4 address... and doing a "ping -4 machinename" from itself gives the correct IPv4 address.... but pinging it regularly from itself gives "::1:".
How can I get the IPv4 for this machine, from itself?
Have you looked at all the addresses in the return, discard the ones of family InterNetworkV6 and retain only the IPv4 ones?
To find all local IPv4 addresses:
IPAddress[] ipv4Addresses = Array.FindAll(
Dns.GetHostEntry(string.Empty).AddressList,
a => a.AddressFamily == AddressFamily.InterNetwork);
or use Array.Find or Array.FindLast if you just want one.
IPHostEntry ipHostInfo = Dns.GetHostEntry(serverName);
IPAddress ipAddress = ipHostInfo.AddressList
.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork);
public Form1()
{
InitializeComponent();
string myHost = System.Net.Dns.GetHostName();
string myIP = null;
for (int i = 0; i <= System.Net.Dns.GetHostEntry(myHost).AddressList.Length - 1; i++)
{
if (System.Net.Dns.GetHostEntry(myHost).AddressList[i].IsIPv6LinkLocal == false)
{
myIP = System.Net.Dns.GetHostEntry(myHost).AddressList[i].ToString();
}
}
}
Declare myIP and myHost in public Variable
and use in any function of the form.
public static string GetIPAddress(string hostname)
{
IPHostEntry host;
host = Dns.GetHostEntry(hostname);
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
//System.Diagnostics.Debug.WriteLine("LocalIPadress: " + ip);
return ip.ToString();
}
}
return string.Empty;
}
To find all valid address list this is the code I have used
public static IEnumerable<string> GetAddresses()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
return (from ip in host.AddressList where ip.AddressFamily == AddressFamily.lo select ip.ToString()).ToList();
}
You can get all IPv4 address from the DNS using this code:
IPs[] ipv4Addresses = Array.FindAll(
Dns.GetHostEntry(string.Empty).AddressList,
address => address.AddressFamily == AddressFamily.InterNetwork);
IPv6
lblIP.Text = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName).AddressList(0).ToString()
IPv4
lblIP.Text = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName).AddressList(1).ToString()

Categories