在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 ...
随机推荐
- dataset 使用
下面有例子说明: 首先我们需要打开一个联结: string MyConnString = "Driver={Microsoft Access Driver (*.mdb)}; DBQ=c:/ ...
- AMBA interconnector PL301(一)
HPM(High-Performance Matrix)是一个自生成的AMBA3 bus subsystem. 由一个AXI bus matrix,Frequency Conversion Compo ...
- enum与typedef enum的用法
一,两者的用法 枚举类型定义用关键字enum标识,形式为: enum 标识符 { 枚举数据表 }:枚举数据(枚举常量)是一些特定的标识符,标识符代表什么含义,完全由程序员决定.数据枚举的顺序规定了枚举 ...
- ApkDec android反编译工具
转自:http://www.newasp.net/soft/70498.html 下载 ApkDec是一款免费的绿色APK反编译工具 forandroid ,由android开发者社区开发. ApkD ...
- NEON在Android中的使用举例【转】
转自:http://blog.csdn.net/fengbingchun/article/details/37766607 版权声明:本文为博主原创文章,未经博主允许不得转载. 1. 打开Eclip ...
- java多线程中的生产者与消费者之等待唤醒机制@Version1.0
一.生产者消费者模式的学生类成员变量生产与消费demo,第一版1.等待唤醒: Object类中提供了三个方法: wait():等待 notify():唤醒单个线程 notify ...
- Linux中PHP如何安装curl扩展方法
如果php已经在系统编译好,后来又需要添加新的扩展. 一种方式就是重新完全编译php,另一种方式就是单独编译扩展库,以extension的形式扩展. 下面以安装curl扩展为例: 1.下载curl安装 ...
- cocos2dx lua bug之module 'lsqlite3' not found
05-27 15:41:01.360: D/cocos2d-x debug info(7261): [LUA-print] -------------------------------------- ...
- 集合(Collection)使用笔记
Collections.unmodifiableCollection这个可以得到一个集合的镜像,它的返回结果不可直接被改变,否则会提示 java.lang.UnsupportedOperationEx ...
- c# 回调委托
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...