在Window Embedded CE(Wince)下使用OpenNETCF进行路由表的开发
点击打开链接
背景
在开发3G项目的是时候,发现尽管3G网络连接已经建立成功了,但是数据不能发送成功,查明原因,由于路由表的问题,导致数据往ActiveSync连接的对端,也就是PC发送,而不是发送到3G网络的拨号服务器去。本文讲述如何使用OpenNETCF来修改路由表。
什么是路由表(Routing Table)
先看一个Window Embedded CE的路由表
![]()
路由表是存储在路由器或者联网计算机上的一个电子表格或者数据库。本来路由表不仅仅使用在TCP/IP网络,IPX也使用路由表。但是目前流行使用路由表的网络只有TCP/IP。在TCP/IP网络,这表格指定IP包的流向,如上图可见,Destination和Netmask表示需要发送的目的地和及其掩码。GatewayAddress表示该Destination的包需要发送到的网关。Interface表示本机上网卡的地址,这个地址和Destination可以直接通信。Metric表示发送包的成本,是一个从0到9999的整数,数值越低表示成本越低,这条路径越可靠。
问题
当我拨通3G网络的时候,还是ping不通google,如下图:
![]()
原因出在路由表上,如下图:
![]()
google的地址是66.102.11.99,不在路由表内,会走默认路由,也就是0.0.0.0的路由配置.但是默认路由确有两条,而且Metric都是一样的。通过老王(王坚)的指导,那样的情况下,Windows 会自动选择速率快的网卡来传输数据,由于192.168.55.100是USB的ActiveSync连接,而10.250.47.212是3G网络连接,由于USB速度比3G网络快,所以发送到google.com(66.102.11.99)的包被默认发送到192.168.55.100去了。而192.168.55.100没有帮这台Wince机器做往internet的路由,所以wince机器没办法ping通google。
方案
解决这个问题可以有几个方案。
方案一,为目标地址加上路由,例如为google.com(66.102.11.99)加上路由,让它走10.250.47.212出,但是这方案不好,因为我的应用配置都是DNS名字,以后不知道到底IP是怎样,所以没办法为特定IP加路由。
方案二,删除指向192.168.55.100的默认路由。这个方案能满足我的需求,但是有时候需要用回ActiveSync的话需要增加原有的路由。
方案三,修改Metric的值,使得指向192.168.55.100的模拟路由优先选择。我的做法就是使用这个方案的。
实现
OpenNETCF的IPRoutingTable类大大简化了路由表开发的难度。
![]()
IPRoutingTable是一个容器类,封装了一个路由表格,每一条单独记录由IPForwardEntry类表达。IPForwardEntry类如下图所示。
![]()
IPForwardEntry类表示路由表中单独的一条记录。IPRoutingTable可以查看,新增,删除和修改路由表里面的项。其实增删改查路由表的操作都是通过P/Invoke iphlpapi.dll的API来完成的,关于P/Invoke 可以查看我之前的文章。关键API如下:

internal static unsafe extern int DeleteIpForwardEntry(byte[] pRoute);
[DllImport("iphlpapi.dll", SetLastError = true)]
internal static unsafe extern int CreateIpForwardEntry(byte[] pRoute);
[DllImport("iphlpapi.dll", SetLastError = true)]
internal static unsafe extern int SetIpForwardEntry(byte[] pRoute);
[DllImport("iphlpapi.dll", SetLastError = true)]
internal static unsafe extern int GetIpForwardTable(IntPtr pIpForwardTable, ref int pdwSize, int bOrder);
[DllImport("iphlpapi.dll", SetLastError = true)]
internal static unsafe extern int GetIpForwardTable(byte[] pIpForwardTable, ref int pdwSize, int bOrder);
[DllImport("iphlpapi.dll", SetLastError = true)]
internal static unsafe extern int FlushIpNetTable(int dwIfIndex);

下面是我的实现代码,选择的是方案三。
代码上面是整个程序的代码。下面分开讲一下。通过Singleton可以取出当前机器上的路由表信息。
显示
IPRoutingTable table = IPRoutingTable.GetRoutingTable();
取出IPRoutingTable下的IPForwardEntry 就可以显示整个路由表信息。

{
Console.WriteLine("\r\n*IP Routing Table\r\n====================");
Console.WriteLine(string.Format("{0}{1}{2}{3}{4}",
"[Destination]".PadLeft(15),
"[NetMask]".PadLeft(15),
"[Next Hop]".PadLeft(15),
"[Interface]".PadLeft(15),
"[Metric]".PadLeft(12)));
foreach (IPForwardEntry entry in table)
{
string interfaceName;
if(entry.NetworkInterface == null)
{
interfaceName = "127.0.0.1";
}
else
{
interfaceName = entry.NetworkInterface.CurrentIpAddress.ToString();
}
Console.WriteLine(string.Format("{0}{1}{2}{3}{4}",
entry.Destination.ToString().PadLeft(15),
entry.SubnetMask.ToString().PadLeft(15),
entry.NextHop.ToString().PadLeft(15),
interfaceName.PadLeft(15),
entry.Metric.ToString().PadLeft(12)));
if (entry.Destination.Equals(DefaultRoute))
{
if (entry.NextHop.Equals(ActiveSyncIP))
{
activeSyncRouteMetric = entry.Metric;
}
IPForwardEntry tempEntry = entry.Clone();
routeEntries.Add(tempEntry);
}
}
}

显示当前机器上所有的路由信息。
![]()
删除
Windows Embedded CE和PC对删除的操作有区别,在Wince下只能删除一个Destination,而PC可以删除指向这一Destination的网关。所以在Wince下删除指向这一Destination的网关不方便,需要先删除所有的,然后增加不想删除的。下面的语句是删除操作。
table.Remove(DefaultRoute);
删除默认路由后的路由信息。
![]()
修改
可以直接修改路由表项(IPForwardEntry)信息的属性。
entry.Metric = activeSyncRouteMetric - 1;
新增
新增就是把IPForwardEntry增加到IPRoutingTable里面
table.Add(entry);
新增默认路由后的路由表信息。
![]()
我把3G链接的路由项的Metric修改成49,这样会优先走这条路由信息。这样就能ping通google了。
最近不是很顺利,放个转运风车,点一下转转运。Cheer up.
在Window Embedded CE(Wince)下使用OpenNETCF进行路由表的开发的更多相关文章
- Windows Mobile和Wince(Windows Embedded CE)的字符集问题
背景 开发过Windows Mobile和Wince(Windows Embedded CE)的开发者,特别是Native C++开发者,或多或少都遇到过ANSI字符集和Unicode字符集的转换问题 ...
- Windows Embedded CE 6.0开发环境的搭建
最近开始在学习嵌入式,在这里首先得安装Windows Embedded CE 6.0,其中遇到了很多问题,电脑的系统以及相关配置都会在安装过程中受到影响,因此笔者就安装中的问题以及环境搭建来介绍一下. ...
- wince下sources\sources.cmn\Makefile.def的相关作用
1:首先是Makefile.def: ---------------------------------------- 在所有驱动的makefile中有!INCLUDE $(_MAKEENVROOT) ...
- SD card技术了解并WINCE下SDHC驱动开发(updated)
Suumary: 简单介绍了一下SD卡的历史和发展,同时结合MX31 ADS上的WINCE 下SDHC驱动更深入的了解该硬件的一些行为特点. 了解SD card SD是Secure Digital C ...
- WINCE下进程间通信(二)
WINCE下进程间通信(二) 接着前面的文章<WINCE下进程间通信(一)>,现在介绍进程间通信的另一种方法. 三.管道(消息队列) WINCE并不支持类似于PC机上匿名管道.命名管道的通 ...
- WinCE下SQLCE数据库开发(VS,VB.net,VC++)
WinCE下SQLCE数据库开发(VS,VB.net,VC++) WinCE下SQLCE数据库开发 微软的SQL Server数据库由于其功能强大.方便使用,因此在很多行业都被广泛应用.基于智能设 ...
- WinCE下的串口通信开发(VS2005,VB.Net,VC++)
WinCE下的串口通信开发(VS2005,VB.Net,VC++) WinCE下的串口通信开发 一.利用Visual Basic 开发很简单,因为有现成的控件可以直接调用 以VS2005为例,首先 ...
- Windows Embedded CE 6.0开发环境的搭建(2)
最近开始在学习嵌入式,在这里首先得安装Windows Embedded CE 6.0,其中遇到了很多问题,电脑的系统以及相关配置都会在安装过程中受到影响,因此笔者就安装中的问题以及环境搭建来介绍一下. ...
- WinCE下读取注册表获得SD路径
WinCE下读取注册表获得SD路径 [要点]WinCE注册表中[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory\] 下键Folde ...
随机推荐
- java 网络编程(一)---基础知识和概念了解
java 为用户提供了十分完善的网络功能: 1. 获取网络上的各种资源(URL) 2. 与服务器建立连接和通信(ServerSocket和Socket) 3. 无连接传递本地数据(DatagramSo ...
- 【sinatra】修改默认ip绑定
加入 # 默认的bind是127.0.0.1 set :bind, '0.0.0.0' #0.0.0.0之后你能通过lan访问这个服务器
- 【py网页】urllib.urlretrieve远程下载
下面我们再来看看 urllib 模块提供的 urlretrieve() 函数.urlretrieve() 方法直接将远程数据下载到本地. 1 >>> help(urllib.urlr ...
- sql2005镜像实现
-- =========================================== -- 无论是主体服务器.镜像服务器, 还是见证服务器 -- 除特别说明外,均需要保证下面的操作 ...
- iOS 学习笔记 十三 (2015.04.15)采用第三方库,实现ios录音转为amr
1.第三方开源库地址 https://github.com/guange2015/ios-amr 2.参考博客地址 http://blog.csdn.net/windsoul85/article/de ...
- 那些情况该使用它们spin_lock到spin_lock_irqsave【转】
转自:http://blog.csdn.net/wesleyluo/article/details/8807919 权声明:本文为博主原创文章,未经博主允许不得转载. Spinlock的目的是用来同步 ...
- Memcached 分布式缓存实现原理
摘要 在高并发环境下,大量的读.写请求涌向数据库,此时磁盘IO将成为瓶颈,从而导致过高的响应延迟,因此缓存应运而生.无论是单机缓存还是分布式缓存都有其适应场景和优缺点,当今存在的缓存产品也是数不胜数, ...
- struts2的两个核心配置文件
struts2的两个核心配置文件,即:struts.default.xml和struts.properties A,位置:都在struts2-core-version.jar文件中 B,作用,stru ...
- .Net额外小工具
http://blog.csdn.net/zhumi/article/details/49076 用于编写单元测试的 NUnit用于创建代码文档资料的 NDoc用于生成解决方案的 NAnt用于生成代码 ...
- C#的OpenFileDialog和SaveFileDialog的常见用法(转)
OpenFileDialog openFileDialog1 = new OpenFileDialog(); openFileDialog1.InitialDirectory = ...