C#获取真实IP地址(IP转为长整形、判断是否内网IP的方法)

所属分类: 软件编程 / C#教程 阅读数: 60
收藏 0 赞 0 分享

今天查看登录日志,发现http_x_forwarded_for获取到的ip地址有些是内网ip地址,有些则是公网和内网ip地址一起获取到,用逗号分隔开,日志截图如下:

之前获取ip地址的C#代码如下:

复制代码 代码如下:

    /// <summary>
    /// C#获取客户端真实IP地址
    /// </summary>
    /// <returns></returns>
    public static string GetIP()
    {
        string ip = HttpContext.Current.Request.ServerVariables["http_x_forwarded_for"];
        if (UserCheck.IsNull(ip)) ip = HttpContext.Current.Request.ServerVariables["remote_addr"];
        return ip;
    }

看来http_x_forwarded_for应该是被其他软件或者ISP修改过了,导致http_x_forwarded_for得不到真实的代理ip地址。之前登陆日志是要判断ip地址是否在允许的ip段内的,这样导致无法登陆系统。最后修改代码如下,增加判断是否为内网或者私有地址,是否符合ipv4的地址规格,不符合还是使用remote_addr来获取客户端的ip地址。

比较安全的获取真实地址的实现代码:

复制代码 代码如下:

 /// <summary>
    /// C#将IP地址转为长整形
    /// </summary>
    /// <param name="ip"></param>
    /// <returns></returns>
    public static long IpToNumber(string ip)
    {
        string[] arr = ip.Split('.');
        return 256 * 256 * 256 * long.Parse(arr[0]) + 256 * 256 * long.Parse(arr[1]) + 256 * long.Parse(arr[2]) + long.Parse(arr[3]);
    }
    /// <summary>
    /// C#判断IP地址是否为私有/内网ip地址
    /// </summary>
    /// <param name="ip"></param>
    /// <returns></returns>
    public static bool IsPrivateIp(string ip)
    {
        long ABegin = IpToNumber("10.0.0.0"), AEnd = IpToNumber("10.255.255.255"),//A类私有IP地址
         BBegin = IpToNumber("172.16.0.0"), BEnd = IpToNumber("172.31.255.255"),//'B类私有IP地址
         CBegin = IpToNumber("192.168.0.0"), CEnd = IpToNumber("192.168.255.255"),//'C类私有IP地址
         IpNum = IpToNumber(ip);
        return (ABegin <= IpNum && IpNum <= AEnd) || (BBegin <= IpNum && IpNum <= BEnd) || (CBegin <= IpNum && IpNum <= CEnd);
    }
    /// <summary>
    /// C#获取真实IP地址
    /// </summary>
    /// <returns></returns>
    public static string GetIP()
    {
        string ip = HttpContext.Current.Request.ServerVariables["http_x_forwarded_for"];
        if (UserCheck.IsNull(ip)) ip = HttpContext.Current.Request.ServerVariables["remote_addr"];
        else//代理ip地址有内容,判断是否符合ipv4地址或者是否为内网地址
        {
            ip = ip.Trim().Replace(" ", "");
            if (!Regex.IsMatch(ip, @"^\d+(\.\d+){3}$") || IsPrivateIp(ip))
                ip = HttpContext.Current.Request.ServerVariables["remote_addr"];//不符合规则或者内网/私有地址使用remote_addr代替
        }
        return ip;
    }

2014-07-02更新:原来是 cdn加速的问题,cdn加速后,由于先判断http_x_forwarded_for,http_x_forwarded_for是随便可以伪造的,放置任何内容的,所以下图出现的ip地址中会有内网地址或者出现2个ip地址的问题。所以获取http_x_forwarded_for内容时需要 split下获取第一个项。

更多精彩内容其他人还在看

C#学习笔记之状态模式详解

这篇文章主要为大家详细介绍了C#学习笔记之状态模式的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

C# 字符串、数组和List的截取和转换实例

下面小编就为大家分享一篇C# 字符串、数组和List的截取和转换实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

c#打包文件解压缩的实例

下面小编就为大家分享一篇c#打包文件解压缩的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

浅谈C#跨线程调用窗体控件(比如TextBox)引发的线程安全问题

下面小编就为大家分享一篇浅谈C#跨线程调用窗体控件(比如TextBox)引发的线程安全问题,具有很好的参考价值,希望对大家有所帮助
收藏 0 赞 0 分享

判断一个整数是否是2的N次幂实现方法

下面小编就为大家分享一篇判断一个整数是否是2的N次幂实现方法,实例简洁,具有很好的参考价值。希望对大家有所帮助
收藏 0 赞 0 分享

浅谈c#中config.exe 引发的一些问题

下面小编就为大家分享一篇浅谈c#中config.exe 引发的一些问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

基于C#开发中的那些编码问题(详谈)

下面小编就为大家分享一篇基于C#开发中的那些编码问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

C#实现WPS文件转PDF格式的方法示例

这篇文章主要介绍了C#实现WPS文件转PDF格式的方法,涉及C#针对office组件的相关引用与操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

C#实现的文件上传下载工具类完整实例【上传文件自动命名】

这篇文章主要介绍了C#实现的文件上传下载工具类,结合完整实例形式分析了C#操作文件上传与下载功能,并且还可针对上传文件自动命名以避免服务器中的文件名重复,需要的朋友可以参考下
收藏 0 赞 0 分享

C# Socket 发送&接收&返回 简单应用实例

下面小编就为大家分享一篇C# Socket 发送&接收&返回 简单应用实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享
查看更多