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

起因:凡是网络程序,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地址的更多相关文章

  1. LinuxC下获取UDP包中的路由目的IP地址和头标识目的地址

    在接受到UDP包后,有时候我们需要根据所接收到得UDP包,获取它的路由目的IP地址和头标识目的地址. (一)主要的步骤: 在setsockopt中设置IP_PKTINFO,然后通过recvmsg来获取 ...

  2. Windows 系统采用批处理命令修改 ip 地址

    Windows 系统采用批处理命令修改 ip 地址 :: 设置IP地址 set /p choice=请选择设置类型(1:外网IP / 2:内网IP / 3:自动获取IP): echo. if &quo ...

  3. asp.net中获得客户端的IP地址

    asp.net中获得客户端的IP地址 因为要在项目中取到客户端IP,在网上搜了下相关资料,其中有一篇文章总结的比较详细,这里就把一些我用的上总结一下 方便以后查阅.  通常我们都通过下面的代码获得IP ...

  4. 【liunx】使用xshell连接虚拟机上的CentOS 7,使用xhell连接本地虚拟机上的Ubuntu, 获取本地虚拟机中CentOS 7的IP地址,获取本地虚拟机中Ubuntu 的IP地址,Ubuntu开启22端口

    注意,如果想用xshell去连接本地虚拟机中的linux系统,需要本地虚拟机中的系统是启动的才能连接!!!!! ============================================ ...

  5. Vmware虚拟中克隆主机没IP地址?怎么解决?

    Vmware虚拟中克隆主机没IP地址?怎么解决? 修改网卡的配置文件:  清空如下的文件: 重启主机即可!  

  6. shell中获取本机ip地址

    shell中获取本机ip地址 方法一: /sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr ...

  7. Ubuntu系统中连接TFS的Git地址注意事项

    在Ubuntu中安装Git后,配置远程Git服务器地址,如果是TFS的Git仓库地址,则需要使用IP地址,否则可能出现识别不出来的问题; 再者,如果你想要在Ubuntu的浏览中访问TFS的Git仓库U ...

  8. 分享:linux系统如何快速阻止恶意IP地址

    可能你想要在各种情形下阻止有人通过IP地址访问你的Linux系统.比如说,作为最终用户,你可能想要保护自己,避免已知的间谍软件或跟踪者的IP地址.或者如果你在运行P2P软件,可能想要把来自与违反P2P ...

  9. (转)asp.net中获得客户端的IP地址

    因为要在项目中取到客户端IP,在网上搜了下相关资料,其中有一篇文章总结的比较详细,这里就把一些我用的上总结一下 方便以后查阅. 通常我们都通过下面的代码获得IP:   string ip =Syste ...

随机推荐

  1. C#操作Xml:XmlSerializer 对象的Xml序列化和反序列化

    这篇随笔对应的.Net命名空间是System.Xml.Serialization:文中的示例代码需要引用这个命名空间. 为什么要做序列化和反序列化? .Net程序执行时,对象都驻留在内存中:内存中的对 ...

  2. event.srcElement与event.target的区别

    window.event.srcElement与window.event.target 都是指向触发事件的元素,它是什么就有什么样的属性 srcElement是事件初始化目标html元素对象引用,因为 ...

  3. 【百度地图API】如何制作班级地理通讯录?LBS通讯录

    原文:[百度地图API]如何制作班级地理通讯录?LBS通讯录 摘要:班级通讯录必备的功能,比如人员列表,人员地理位置标注,展示复杂信息窗口,公交和驾车等.一般班级人员都不会超过300个,因为可以高效地 ...

  4. 【百度地图API】交你如何用百度地图搜索自己的数据!不需数据库!

    原文:[百度地图API]交你如何用百度地图搜索自己的数据!不需数据库! 摘要: 我有一定的房产数据,还有银行数据.我想在百度地图上标注出来,并且能搜索到我这些数据. 可是百度的数据库上并没有我的数据. ...

  5. __doPostBack 未生成

    事情是这样的: asp.net 项目 采用了 DevExpress 第三方控件,然后 网站架设在  win2003 服务器上面. 本地测试 都是 OK的,然而 ,在服务器 上面 却出现了  __doP ...

  6. Asp.net MVC + EF + Spring.Net 项目实践(一)

    准备用几篇文章来做一个MVC的例子,为了给新同事做参考,也为自己做个知识储备. 首先,用VS2013创建一个空白解决方案StudentManageSystem,然后添加一个MVC应用程序(可参考ASP ...

  7. SoC嵌入式软件架构设计II:否MMU的CPU虚拟内存管理的设计与实现方法

    大多数的程序代码是必要的时,它可以被加载到内存中运行.手术后,可直接丢弃或覆盖其他代码.我们PC然在同一时间大量的应用,能够整个线性地址空间(除了部分留给操作系统或者预留它用),能够觉得每一个应用程序 ...

  8. Linux httpd 跳转简单方法二

    使用mod_proxy 这种方法要添加上mod_proxy_http.so 在httpd.conf 中打开httpd-vhost 在 httpd-vhost 里面添加上 <VirtualHost ...

  9. java设计模式之六适配器模式(Adapter)

    适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题.主要分为三类:类的适配器模式.对象的适配器模式.接口的适配器模式.首先,我们来看看类的适配器模 ...

  10. PE文件结构(五岁以下儿童)基地搬迁

    PE文件结构(五岁以下儿童) 參考 书:<加密与解密> 视频:小甲鱼 解密系列 视频 基址重定位 链接器生成一个PE文件时,它会如果程序被装入时使用的默认ImageBase基地址(VC默认 ...