欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#如何自动选择出系统中最合适的IP地址

程序员文章站 2023-11-16 22:46:16
写这个是因为很长时间以来,碰到过很多次这个问题,但都没当回事,这次又碰到了这个老问题,无奈百度了一圈儿未果,身边又没有大牛可以请教,就自己先“总结”了一套方法,一来给自己记...

写这个是因为很长时间以来,碰到过很多次这个问题,但都没当回事,这次又碰到了这个老问题,无奈百度了一圈儿未果,身边又没有大牛可以请教,就自己先“总结”了一套方法,一来给自己记录,二来如果碰巧能有朋友看到并为他解决了同样的困扰我将感到很爽。

起因:凡是网络程序,coder似乎不可避免要碰到,你的代码如何在不同的机器上挑选出最合适的那个ip来通讯,因为如果打开一个应用程序让用户来选择用哪个ip地址和端口来通讯似乎就代表着这是个多么低端的程序,多么低能的程序员,所以一定要自动选择,用户 0 感知,就像伟大的qq那样。我也再次碰到了这个事情,q群未果百度未果,就自己用 framework 中提供的方法和属性,自己总结了一个“规则”,下面直奔主题。

现在的机器可能是双网卡,可能因为各类软件和驱动又有多个虚拟网卡,所以我的“规则”是不直接判断 ip 是不是符合规定,而是先从 networkinterface 入手,下面总结一下:

  1. 获取所有本地 networkinterface 对象;

  2. 其属性 type 最好为 wireless80211、ethernet、fddi、ppp等,因为根据 msdn 的解释这几类会是普通家用电脑常见的接口类型,但这样判断不太准确,所以只作为辅助判断条件;

  3. 其属性 operationalstatus 应该为 up,根据 msdn 解释,仅在 up 时表示该网络接口是可以正常收发数据的,这也可以作为判断网卡(网络)是否可用的一个条件;

  4. 使用 getipproperties().unicastaddresses 方法,获取该网络接口下所有单播地址,这可以让你获得网络ip;

  5. 该ip的duplicateaddressdetectionstate属性应该为 preferred,表示地址有效,即ip地址可正常使用;

  6. 该ip的属性 prefixorigin 其值应该为 dhcp 或 manual,表示ip前缀由 dhcp 分配或手动指定;

  7. 该ip的属性 suffixorigin 其值应该为 origindhcp 或 manual,表示ip后缀由 dhcp 分配或手动指定;

  综上所述,基本可以排除一些如 169 、127.0.0.1 等此类的特殊地址,还有一些乱七八糟不知有什么用的网络接口(有的网络接口没有地址,有的只有ipv6地址),但我感觉我这方法应该不是个“正路”,希望能有有经验的人看到给我指点迷津。

  以下贴出测试用的截图和代码,是我机器上的结果:

C#如何自动选择出系统中最合适的IP地址

代码:

var interfacelist = networkinterface.getallnetworkinterfaces();
      stringbuilder sb = new stringbuilder(512);
      int index = 0;
      string message = string.empty;

      foreach(var item in interfacelist)
      {
        index++;

        sb.appendline(string.format("interface{0}: {1}", index, item.name));
        sb.appendline(string.format("description: {0}", item.description));
        sb.appendline(string.format("id: {0}", item.id));
        sb.appendline(string.format("type: {0}", item.networkinterfacetype));
        sb.appendline(string.format("operationalstatus: {0}", item.operationalstatus));
        sb.appendline(string.format("isreceiveonly: {0}", item.isreceiveonly));
        sb.appendline(string.format("speed: {0}", item.speed));
        sb.appendline(string.format("supportmulticast: {0}", item.supportsmulticast));
        sb.appendline(string.format("supportipv4: {0}", item.supports(networkinterfacecomponent.ipv4)));

        sb.appendline(string.format("ip properties:"));
        var addresses = item.getipproperties().unicastaddresses;
        int j = 0;
        foreach (var ip in addresses)
        {
          j++;
          sb.appendline(string.format("address{0}: {1}({2})", j, ip.address.tostring(),ip.address.addressfamily));
          sb.appendline(string.format("ipv4 mask: {0}", ip.ipv4mask));
          sb.appendline(string.format("prefixorigin: {0}", ip.prefixorigin));
          sb.appendline(string.format("suffixorigin: {0}", ip.suffixorigin));
          sb.appendline(string.format("duplicateaddressdetectionstate: {0}", ip.duplicateaddressdetectionstate));
        }
        sb.appendline();
      }

      textbox1.text = sb.tostring();

以上就是本文的全部内容,希望对大家的学习有所帮助。