在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如下:
????????[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进行路由表的开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于三星A7屏幕锁已由管理员、加密政策,
- 下一篇: 液晶屏工作稳定说明