C#自动选择出系统中最合适的IP地址
写这个是因为很长时间以来,碰到过很多次这个问题,但都没当回事,这次又碰到了这个老问题,无奈百度了一圈儿未果,身边又没有大牛可以请教,就自己先“总结”了一套方法,一来给自己记录,二来如果碰巧能有朋友看到并为他解决了同样的困扰我将感到很爽。
起因:凡是网络程序,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地址),但我感觉我这方法应该不是个“正路”,希望能有有经验的人看到给我指点迷津。
以下贴出测试用的截图和代码,是我机器上的结果:

偷懒代码:
var interfaceList = NetworkInterface.GetAllNetworkInterfaces();
StringBuilder sb = new StringBuilder();
int index = ;
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 = ;
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();
C#自动选择出系统中最合适的IP地址的更多相关文章
- LinuxC下获取UDP包中的路由目的IP地址和头标识目的地址
在接受到UDP包后,有时候我们需要根据所接收到得UDP包,获取它的路由目的IP地址和头标识目的地址. (一)主要的步骤: 在setsockopt中设置IP_PKTINFO,然后通过recvmsg来获取 ...
- Windows 系统采用批处理命令修改 ip 地址
Windows 系统采用批处理命令修改 ip 地址 :: 设置IP地址 set /p choice=请选择设置类型(1:外网IP / 2:内网IP / 3:自动获取IP): echo. if &quo ...
- asp.net中获得客户端的IP地址
asp.net中获得客户端的IP地址 因为要在项目中取到客户端IP,在网上搜了下相关资料,其中有一篇文章总结的比较详细,这里就把一些我用的上总结一下 方便以后查阅. 通常我们都通过下面的代码获得IP ...
- 【liunx】使用xshell连接虚拟机上的CentOS 7,使用xhell连接本地虚拟机上的Ubuntu, 获取本地虚拟机中CentOS 7的IP地址,获取本地虚拟机中Ubuntu 的IP地址,Ubuntu开启22端口
注意,如果想用xshell去连接本地虚拟机中的linux系统,需要本地虚拟机中的系统是启动的才能连接!!!!! ============================================ ...
- Vmware虚拟中克隆主机没IP地址?怎么解决?
Vmware虚拟中克隆主机没IP地址?怎么解决? 修改网卡的配置文件: 清空如下的文件: 重启主机即可!
- shell中获取本机ip地址
shell中获取本机ip地址 方法一: /sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr ...
- Ubuntu系统中连接TFS的Git地址注意事项
在Ubuntu中安装Git后,配置远程Git服务器地址,如果是TFS的Git仓库地址,则需要使用IP地址,否则可能出现识别不出来的问题; 再者,如果你想要在Ubuntu的浏览中访问TFS的Git仓库U ...
- 分享:linux系统如何快速阻止恶意IP地址
可能你想要在各种情形下阻止有人通过IP地址访问你的Linux系统.比如说,作为最终用户,你可能想要保护自己,避免已知的间谍软件或跟踪者的IP地址.或者如果你在运行P2P软件,可能想要把来自与违反P2P ...
- (转)asp.net中获得客户端的IP地址
因为要在项目中取到客户端IP,在网上搜了下相关资料,其中有一篇文章总结的比较详细,这里就把一些我用的上总结一下 方便以后查阅. 通常我们都通过下面的代码获得IP: string ip =Syste ...
随机推荐
- C#/.NET code
Some practices to write better C#/.NET code(译) C#(.NET)中有关编码的一些建议,原文地址:http://www.codeproject.com/Ar ...
- php_中替换换行符
//php 有三种方法来解决 //1.使用str_replace 来替换换行 $str = str_replace(array("\r\n", "\r", &q ...
- HDU 1102 Constructing Roads, Prim+优先队列
题目链接:HDU 1102 Constructing Roads Constructing Roads Problem Description There are N villages, which ...
- 【Stackoverflow好问题】java在,如何推断阵列Array是否包括指定的值
问题 java中,怎样推断数组Array是否包括指定的值 精华回答 1. Arrays.asList(...).contains(...) 2. 使用 Apache Commons Lang包中的Ar ...
- POJ3342——Party at Hali-Bula
Party at Hali-Bula Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5418 Accepted: 192 ...
- C语言学习之路,第一篇章。
看的书是 C primer plus ,这本书好评很多, 学过C#,没有精通,了解Java,所以看这本书会很容易上手,编译器用的是VC++6.0,因为VS2010好像不支持C99标准,有些代码功能 ...
- JVM截至多少线程可以创建: unable to create new native thread
最近的测试需要很长的连接server.这些数据需要达到100W长连接,试client.一个线程来保持连接.查找linuxserver创建者默认3200当多个线程.这个错误将得到"java.l ...
- Enum:枚举
原文:Enum:枚举 枚举 (enum) 是值类型的一种特殊形式,它从 System.Enum 继承而来,并为基础的基元类型的值提供替代名称.枚举类型有名称.基础类型和一组字段.基础类型必须是一个内置 ...
- openstack shelve/unshelve/stop浅析
声明: 本博客欢迎转发,但请保留原作者信息! 博客地址:http://blog.csdn.net/halcyonbaby 内容系本人学习.研究和总结,如有雷同,实属荣幸! stop的虚拟机仅仅是将虚拟 ...
- Java对象比较器对泛型List进行排序-Demo
针对形如:字段1 字段2 字段3 字段n 1 hello 26 7891 world 89 5562 what 55 4562 the 85 452 fuck 55 995 haha 98 455 以 ...