【问题标题】:ip address increment problemip地址递增问题
【发布时间】:2011-03-29 20:01:51
【问题描述】:

我想增加我的ip地址和;

这里是代码

 ipAddressControl1.Text = "192.168.1.255";

 byte[] ip = ipAddressControl1.GetAddressBytes();
 ip[3] = (byte)(++ip[3]);

 IPAddress ipAddress1 = new IPAddress(ip);
 MessageBox.Show(ipAddress1.ToString());

或者我也试过这个

ipAddressControl3.Text = "192.168.1.255";
 IPAddress ipAddress1 = new IPAddress(ıpAddressControl3.GetAddressBytes());
 ipAddress1.Address += 0x1 << 24;
 MessageBox.Show(ipAddress1.ToString());

但他们都给了我 192.168.1.0 但我想获得价值 192.168.2.0

【问题讨论】:

标签: c# ip-address ip


【解决方案1】:

您需要检查您的地址是否为 254 - 255 和 0 是否为广播地址。

ipAddressControl1.Text = "192.168.1.255";

byte[] ip = ipAddressControl1.GetAddressBytes();
if (ip[3] != 255)
{
    ip[3] = (byte)(++ip[3]);
}
else
{
    ip[2] = (byte)(++ip[2]);
    ip[3] = (byte)0;
}
IPAddress ipAddress1 = new IPAddress(ip);
MessageBox.Show(ipAddress1.ToString());

但您只能检查直到 ip[0] 的溢出 - 如果您在此处达到 255,则需要小心。

【讨论】:

  • 为什么要使用多余的增量和分配?
【解决方案2】:

您的问题是当ip[3] 环绕时,您没有增加ip[2](依此类推)。下面的代码应该可以解决问题,最后从255.255.255.255 包装到0.0.0.0

byte[] ip = ipAddressControl1.GetAddressBytes();
ip[3] = (byte)(ip[3] + 1);
if (ip[3] == 0) {
    ip[2] = (byte)(ip[2] + 1);
    if (ip[2] == 0) {
        ip[1] = (byte)(ip[1] + 1);
        if (ip[1] == 0) {
            ip[0] = (byte)(ip[0] + 1);
        }
    }
}

以下方法也可能起作用:

byte[] ip = ipAddressControl1.GetAddressBytes();
if (++ip[3] == 0)
    if (++ip[2] == 0)
        if (++ip[1] == 0)
            ++ip[0];

【讨论】:

  • 为什么要冗余双增量?
  • @silky,如果您愿意,请随时使用“更漂亮”的代码发布答案。如果您只是将第一段作为注释放入代码中,那么这对我和其他任何人来说都是完全可读的。我,我更喜欢功能而不是形式。
  • @paxdiablo:为了清楚起见,我并没有对你投反对票(事实上,恰恰相反)。
  • @paxdiablo,我的意思是您使用了++,但随后也分配了结果。您现在已将其更改为 + 1,但我真的不明白为什么您不能只写 ip[3]++ 并取消演员表。
  • @silky,没关系,我不会屈服于报复性打击。
【解决方案3】:

在第一个示例中,您只增加了第 4 个字节序列。所以它将从 255 变为 0,而对 byte[2] 没有影响。

在第二个序列中,您将其递增 1,但随后将其从 2 移回 1。我不确定您为什么选择这样做。

【讨论】:

    【解决方案4】:

    看起来 IP 地址以“错误的方式”存储在您尝试使用的 .Address 属性中:

    192.168.1.255
     c0 a8 01 ff     is stored as   0xff01a8c0
    

    所以添加1 &lt;&lt; 24 只会增加左边的0xff 然后截断它,变成0

    如果您希望它按照您描述的方式工作,您必须编写自己的加法函数。

    public static IPAddress IncrementIP(IPAddress addr)
    {
        byte[] ip = addr.GetAddressBytes();
        ip[3]++;
        if (ip[3] == 0) {
            ip[2]++;
            if (ip[2] == 0) {
                ip[1]++;
                if (ip[1] == 0)
                    ip[0]++;
            }
        }
        return new IPAddress(ip);
    }
    

    或类似的东西。

    【讨论】:

      【解决方案5】:

      您可以将 IP 转换为等效的数字。

      查看这个先前回答的问题以了解详细信息:

      Best type for IP-address in Hibernate Entity?

      public static string GetStandardIP(long numericIP)
          {
              string w = Convert.ToString(Convert.ToInt64(numericIP / 16777216) % 256);
              string x = Convert.ToString(Convert.ToInt64(numericIP / 65536) % 256);
              string y = Convert.ToString(Convert.ToInt64(numericIP / 256) % 256);
              string z = Convert.ToString(Convert.ToInt64(numericIP) % 256);
      
              return w + "." + x + "." + y + "." + z;
          }
      

      还有这个

      public static long GetNumericIP(string standardIP)
          {
                  if (standardIP != null && standardIP != string.Empty)
                  {
                      string[] ipParts = standardIP.Split('.');
                      long numericIP = 16777216 * Convert.ToInt64(ipParts[0]) + 65536 * Convert.ToInt64(ipParts[1]) + 256 * Convert.ToInt32(ipParts[2]) + Convert.ToInt32(ipParts[3]);
      
                      return numericIP;
                  }
                  return 0;
          }
      

      您可能希望通过检查参数并使用 string.concat 来改进它们

      【讨论】:

        【解决方案6】:

        可能值得注意的是,现有的答案都没有处理 IPv6 地址,IPAddress 类本身确实可以满足这些要求。为此,您可能希望采用更通用的策略(我不确定 IPv6 的增量规则是什么样的,尽管它们可能完全相同,只是需要更多字节来完成,我怀疑这是案例)。

        -- 编辑:

        在此基础上,这似乎可行:

            public static IPAddress Increment (IPAddress address)
            {
                IPAddress result;
        
                byte[] bytes = address.GetAddressBytes();
        
                for(int k = bytes.Length - 1; k >= 0; k--){
                    if( bytes[k] == byte.MaxValue ){
                        bytes[k] = 0;
                        continue;
                    }
        
                    bytes[k]++;
        
                    result = new IPAddress(bytes);
                    return result;
                }
        
                // Un-incrementable, return the original address.
                return address;
            }
        

        【讨论】:

        • 不错!我希望你也添加减量。
        【解决方案7】:

        我强烈不同意提供的答案。它确实有效,但我可以看到它存在严重的问题,首先是可读性。在我看来,可读性和可维护性是最重要的,而公认的解决方案根本行不通。除此之外,更通用的方法也将解决 IPv6 的问题,而公认的解决方案将不起作用。

        我的建议是使用以下方法:

            public static IPAddress AddOne(this IPAddress ipAddress)
            {
                byte[] data = ipAddress.GetAddressBytes();
        
                IncrementByOneFromRight(data, data.Length - 1);
        
                return new IPAddress(data);
            }
        
            private static void IncrementByOneFromRight(byte[] data, int index)
            {
                if (index < 0)
                    return;
        
                if (data[index] < byte.MaxValue)
                    data[index] += 1;
                else
                {
                    data[index] = 0;
        
                    IncrementByOneFromRight(data, index - 1);
                }
            }
        

        将上面的内容放在一个可见的静态类中,AddOne 方法将作为 IPAddress 的扩展方法。这使得使用起来更容易,并且您不会暴露在类中添加到 IPAddress 的具体实现细节,同时保持和可读性。这将有一个额外的好处,即不会用可能不相关的方法使您已经编写的类变得混乱。

        如果您同意我的回答以及我不同意批准的回答的原因,请投票,以便提出此问题的人可以看到这一点。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-10-26
          • 2011-10-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-08
          • 2023-02-22
          相关资源
          最近更新 更多