Ответ 1
Uri url;
IPAddress ip;
if (Uri.TryCreate(String.Format("http://{0}", "127.0.0.1:5"), UriKind.Absolute, out url) &&
IPAddress.TryParse(url.Host, out ip))
{
IPEndPoint endPoint = new IPEndPoint(ip, url.Port);
}
Я пытаюсь разобрать строку, содержащую IP-адрес и порт, используя IPAddress.Parse. Это хорошо работает с адресами IPv6, но не с адресами IPv4. Может ли кто-нибудь объяснить, почему это происходит?
Используемый мной код:
IPAddress.Parse("[::1]:5"); //Valid
IPAddress.Parse("127.0.0.1:5"); //null
Uri url;
IPAddress ip;
if (Uri.TryCreate(String.Format("http://{0}", "127.0.0.1:5"), UriKind.Absolute, out url) &&
IPAddress.TryParse(url.Host, out ip))
{
IPEndPoint endPoint = new IPEndPoint(ip, url.Port);
}
Это происходит потому, что порт не является частью IP-адреса. Он относится к TCP/UDP, и вам придется сначала его отключить. Класс Uri может быть полезен для этого.
IP-адрес не является IP-адресом. Вы хотите IPEndPoint.
Пример из http://www.java2s.com/Code/CSharp/Network/ParseHostString.htm
public static void ParseHostString(string hostString, ref string hostName, ref int port)
{
hostName = hostString;
if (hostString.Contains(":"))
{
string[] hostParts = hostString.Split(':');
if (hostParts.Length == 2)
{
hostName = hostParts[0];
int.TryParse(hostParts[1], out port);
}
}
}
Изменить: Хорошо, я признаю, что это не самое элегантное решение. Попробуйте этот, который я написал (только для вас):
// You need to include some usings:
using System.Text.RegularExpressions;
using System.Net;
// Then this code (static is not required):
private static Regex hostPortMatch = new Regex(@"^(?<ip>(?:\[[\da-fA-F:]+\])|(?:\d{1,3}\.){3}\d{1,3})(?::(?<port>\d+))?$", System.Text.RegularExpressions.RegexOptions.Compiled);
public static IPEndPoint ParseHostPort(string hostPort)
{
Match match = hostPortMatch.Match(hostPort);
if (!match.Success)
return null;
return new IPEndPoint(IPAddress.Parse(match.Groups["ip"].Value), int.Parse(match.Groups["port"].Value));
}
Обратите внимание, что этот ТОЛЬКО принимает IP-адрес, а не имя хоста. Если вы хотите поддерживать имя хоста, вам придется либо разрешить его на IP, либо не использовать IPAddress/IPEndPoint.
IPAddress.Parse предназначен для того, чтобы взять строку, содержащую IP-адрес в обозначении с точками-квадратиками для IPv4 и в шестнадцатеричной кодировке двоеточия для IPv6. Итак, ваш первый пример работает для IPv6, а ваш второй пример терпит неудачу, потому что он не поддерживает порт для IPv4. Ссылка http://msdn.microsoft.com/en-us/library/system.net.ipaddress.parse.aspx