点击打开链接

背景

在开发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如下:

        [DllImport("iphlpapi.dll", SetLastError = true)]
        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 就可以显示整个路由表信息。

        static void Display(IPRoutingTable table)
        {
            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进行路由表的开发的更多相关文章

  1. Windows Mobile和Wince(Windows Embedded CE)的字符集问题

    背景 开发过Windows Mobile和Wince(Windows Embedded CE)的开发者,特别是Native C++开发者,或多或少都遇到过ANSI字符集和Unicode字符集的转换问题 ...

  2. Windows Embedded CE 6.0开发环境的搭建

    最近开始在学习嵌入式,在这里首先得安装Windows Embedded CE 6.0,其中遇到了很多问题,电脑的系统以及相关配置都会在安装过程中受到影响,因此笔者就安装中的问题以及环境搭建来介绍一下. ...

  3. wince下sources\sources.cmn\Makefile.def的相关作用

    1:首先是Makefile.def: ---------------------------------------- 在所有驱动的makefile中有!INCLUDE $(_MAKEENVROOT) ...

  4. SD card技术了解并WINCE下SDHC驱动开发(updated)

    Suumary: 简单介绍了一下SD卡的历史和发展,同时结合MX31 ADS上的WINCE 下SDHC驱动更深入的了解该硬件的一些行为特点. 了解SD card SD是Secure Digital C ...

  5. WINCE下进程间通信(二)

    WINCE下进程间通信(二) 接着前面的文章<WINCE下进程间通信(一)>,现在介绍进程间通信的另一种方法. 三.管道(消息队列) WINCE并不支持类似于PC机上匿名管道.命名管道的通 ...

  6. WinCE下SQLCE数据库开发(VS,VB.net,VC++)

    WinCE下SQLCE数据库开发(VS,VB.net,VC++)   WinCE下SQLCE数据库开发 微软的SQL Server数据库由于其功能强大.方便使用,因此在很多行业都被广泛应用.基于智能设 ...

  7. WinCE下的串口通信开发(VS2005,VB.Net,VC++)

    WinCE下的串口通信开发(VS2005,VB.Net,VC++)   WinCE下的串口通信开发 一.利用Visual Basic 开发很简单,因为有现成的控件可以直接调用 以VS2005为例,首先 ...

  8. Windows Embedded CE 6.0开发环境的搭建(2)

    最近开始在学习嵌入式,在这里首先得安装Windows Embedded CE 6.0,其中遇到了很多问题,电脑的系统以及相关配置都会在安装过程中受到影响,因此笔者就安装中的问题以及环境搭建来介绍一下. ...

  9. WinCE下读取注册表获得SD路径

    WinCE下读取注册表获得SD路径 [要点]WinCE注册表中[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory\] 下键Folde ...

随机推荐

  1. ThinkPHP讲解(六)——添加数据

    添加数据到数据库有三种方式 第一种:使用数组添加 $model=D("Info"); //实例化对象 //添加数据的第一种方式:使用数组添加 //要添加的数组,必须是关联数组,ke ...

  2. 好用的调色软件 ColorSchemer Studio

    软件名叫:ColorSchemer Studio 这是windows平台下的软件

  3. yii2中textarea中的默认值设置

    1. view中显示文本域的位置 <?= $form->field($goods_model, 'goods_introduce')->textArea(['class'=>' ...

  4. 薛非《品悟C-抛弃C程序设计中的谬误与恶习》读后感part1【转】

    薛非<品悟C-抛弃C程序设计中的谬误与恶习>读后感part1 作者:宝贝孙秀楠﹣大连程序员 发表于2012年10月5日由admin 出处:http://sunxiunan.com/?p=2 ...

  5. CSS中的各个选择节点,都有样式最后一个无样式的快捷解决方法

    2.1.3 多标签 多标签选择器一般和html上下文有关,它有以下集中分类 选择一个祖先的所有子孙节点,例如 div p{…} 选择一个父元素的所有直属节点,例如 div > p{…} 选择某一 ...

  6. 互联网公司前端初级Javascript面试题

    互联网公司前端初级Javascript面试题 1.JavaScript是一门什么样的语言,它有哪些特点?(简述javascript语言的特点)JavaScript是一种基于对象(Object)和事件驱 ...

  7. ubuntu下配置java环境【转】

    转自:http://www.cnblogs.com/fnng/archive/2013/01/30/2883815.html 配置JDK环境 下载 登录oracle的网站去下载JDK7 http:// ...

  8. Understanding the RelationshipType Enumeration [AX 2012]

    Understanding the RelationshipType Enumeration [AX 2012] 3 out of 3 rated this helpful - Rate this t ...

  9. MySQL Replication 优化和技巧、常见故障解决方法

    MySQL 主从同步错误(error)解决(转) sql_slave_skip_counter参数 附: 一些错误信息的处理,主从服务器上的命令,及状态信息. 在从服务器上使用show slave s ...

  10. Python精神

    [root@LDAP_slave ~]# python -c "import this" The Zen of Python, by Tim Peters Beautiful is ...