获取本机内网地址
获取内网地址的方法主要有两种思路, 第一种比较简单: 检索所有网卡配置, 根据规则获取自己想要的网卡地址即可。
using System.Net.NetworkInformation;
public string GetInterIPAddress()
{
var localIps = NetworkInterface.GetAllNetworkInterfaces()
.SelectMany(i => i.GetIPProperties().UnicastAddresses.Select(ip => ip.Address));
var interIps = localIps.Where(ip => IsIntranet(ip)).ToList();
if (!interIps.Any())
{
throw new InvalidOperationException("No network adapters with an IPv4 address in the system!");
}
var expectIp = interIps.FirstOrDefault(ip => ip.GetAddressBytes()[0] != 127) ?? interIps.First();
return expectIp.ToString();
}
public static bool IsIntranet(IPAddress ip)
{
byte[] bytes = ip.GetAddressBytes();
switch (bytes[0])
{
case 10:
return true;
case 127:
return bytes[1] == 0 && bytes[2] == 0 && bytes[3] == 1;
case 172:
return bytes[1] < 32 && bytes[1] >= 16;
case 192:
return bytes[1] == 168;
default:
return false;
}
}
获取本机公网地址
由于公网IP是运营商申请分配的,所以单靠本机皮遏制无法获取到, 一个常见的办法是通过访问某个公网服务后, 被访问的服务根据地址查询(下面的客户端地址)可以确定请求者的地址(不一定是发出请求的机器, 所以存在一定不准确性), 目前有公共的服务提供此类功能, 如果担心安全问题,也可以自己搭建一个简单接口来实现, 示例代码如下:
示例代码:
public async Task<string> GetPublicIpAddress()
{
var ipQueryUrls = new[]{
"http://icanhazip.com",
"https://ifconfig.me/ip"
};
foreach (var url in ipQueryUrls)
{
var response = await httpClient.GetStringAsync(url));
if (!string.IsNullOrEmpty(response))
{
return response.Trim('\b', '\t', '\r', '\n');
}
}
return null;
}
获取客户端地址
对于网站应用, 当客户端发生请求时, 可以通过HTTP请求头获取客户端的信息. 一般来说主要通过 X-Forwarded-For
和 X-Real-IP
来获取
这两个请求头不一定100%凑效, 这取决于客户端请求时是否按规范, 以及如果设置了反向代理, 反向代理服务器添加设置了相关的请求头设置
- X-Forwarded-For 会在路由跳转的时候不断向后追加IP地址,格式为 :
ip1,ip2,ip3
, 可以根据需要取, 比如去第一位即表示客户端的地址 - X-Real-IP 一般取决于反向代理服务器是否设置, 例如nginx:
proxy_set_header X-Real-IP $remote_addr;
, 这个字段只有一个IP值, 直接获取即可
示例代码:
public static IPAddress GetClientIp(this HttpContext httpContext)
{
string clientIp;
if (httpContext.Request.Headers.ContainsKey("X-Forwarded-For"))
{
clientIp = httpContext.Request.Headers["X-Forwarded-For"].ToString().Split(',').FirstOrDefault();
return IPAddress.Parse(clientIp);
}
else if (httpContext.Request.Headers.ContainsKey("X-Real-IP"))
{
clientIp = httpContext.Request.Headers["X-Real-IP"].ToString();
return IPAddress.Parse(clientIp);
}
else
{
return httpContext.Connection.RemoteIpAddress;
}
}