在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 ...
随机推荐
- sql 中各种锁随记
一. 为什么要引入锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 丢失更新 A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系 ...
- 夺命雷公狗---微信开发17----自定义菜单的事件推送,响应菜单的CLICK
废话不多说,index.php 代码如下所示: <?php /** * wechat php test */ //define your token require_once "com ...
- Mysql 的存储引擎,myisam和innodb的区别
MyISAM 是非事务的存储引擎,innodb是支持事务的存储引擎. innodb的引擎比较适合于插入和更新操作比较多的应用,而MyISAM 则适合用于频繁查询的应用 . MyISAM --表锁,in ...
- 代码坏味道特别篇————Long parameter List 过长的参数列表
刚开始学习编程时,老师说:讲方法所需要的东西都以参数的形式传入,那是我们好像还没学OO这个东东,要不就弄成全局变量,我擦,全局变量可牛逼了,刚开始学习的时候我们都在用全局变量,可是后来工作了,经理说不 ...
- SqlSever中Index Seek的匹配规则(一)
我们知道在SqlServer中,索引对查询语句的优化起着巨大的作用,一般来说在执行计划中出现了Index Seek的步骤,我们就认为索引命中了.但是Index Seek中有两个部分是值得我们注意的,我 ...
- servlet、genericservlet、httpservlet之间的区别(转)
当编写一个servlet时,必须直接或间接实现servlet接口,最可能实现的方法就是扩展javax.servlet.genericservlet或javax.servlet.http.httpser ...
- android 学习随笔七(网络:图片及文本传输及线程关系 )
主线程.子线程.UI的关系 简单的HTTP请求 -------------------------------------------------------- public class MainAc ...
- iOS delegate, 代理/委托与协议.
之前知知道iOS协议怎么写, 以为真的跟特么java接口一样, 后来发现完全不是. 首先, 说说应用场景, 就是当你要用一个程序类, 或者说逻辑类, 去控制一个storyboard里面的label, ...
- alias function varibales in Linux/GNU and Mac alias命令细说
细说,在古文言中是”奸细佞臣的话“,现如今成了”详细说明“的缩略. alias是MS-DOC中cmds中doskey的counterpart,是”别名“或者”化名“的意思 alias强大之处在于可以化 ...
- 【PHP设计模式 01_DuoTai.php】多态的说明
<?php /** * [多态] * 定义一个抽象类:Tiger,有两个子类:XTiger 和 MTiger */ header("Content-type: text/html; c ...