博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
协议模拟编程之ADSL模式下IP自动换
阅读量:5283 次
发布时间:2019-06-14

本文共 8440 字,大约阅读时间需要 28 分钟。

   在编写一些自动发贴机之类的小软件时,经常会用到自动更换IP的地方,手动切换的话太麻烦了,因此我们总会相当用脚本或自动化程序来代替手工切换ip的活。如果家里连的是“宽带连接”,几句命令就可以自动切换了。

set WShell=createobject("WScript.Shell")WShell.run "RasDial 宽带连接 /Disconnect",vbhide,trueWShell.run "RasDial 宽带连接 用户名 密码",vbhide,true

注意保存为Vbs脚本,如上图。这是很简单的脚本完成的功能,它可以隐藏运行。

下面我们还是说说用C#的代码完成IP自动切换,毕竟很多程序如果手动去切换IP会很不协调,程序会运行出错。

要将已经存在的ADSL宽带连接从连接状态断开,然后再连接,从而强制重新自动分配IP,从而改变IP,完成一系列这样的功能,除了显式调用上述代码中的“RasDial.exe”之外,在网上还可以引用System32目录下的“rasapi32.dll”,以及" Wininet.dll ”一种方法。

下面是具体步骤:

1.引用命名空间:

using System.Runtime.InteropServices;

接下来就是调用Wininet.dll的API函数,用于宽带网络拨号

[System.Runtime.InteropServices.DllImport("Wininet.dll")]      public  static extern Int32 InternetDial(IntPtr hwndParent, string lpszConnectoid, Int32 dwFlags, ref Int32 lpdwConnection, Int32 dwReserved);

顺带申明一下这个函数所引用的类型,这些类型都是直接从Pinvoke.net查找并复制过来的,用于填补InternetDial的参数dwFlags,INTERNET_DIAL_SHOW_OFFLINE是手动拨号(将“取消”按钮替换为“脱机工作”按钮),INTERNET_DIAL_FORCE_PROMPT是系统提示下的手动拨号, INTERNET_DIAL_UNATTENDED是自动拨号。

[Flags]     public enum InternetDialFlags      {          INTERNET_DIAL_FORCE_PROMPT = 0x2000,          INTERNET_DIAL_SHOW_OFFLINE = 0x4000,          INTERNET_DIAL_UNATTENDED = 0x8000      }

 这样一来,我们就可以直接调用这样一句函数用于连接网络了。

int temp = 0;         Adsl.InternetDial(IntPtr.Zero, "", (int)Adsl.InternetDialFlags.INTERNET_DIAL_UNATTENDED, ref temp, 0);

接下来断开网络就稍微"复杂"一点了,先让我们引用RasHangUp这样一个API32函数。这里顺便将RasHangUp需要用的参数类型和结构都直接申明在里面了。

View Code
1  public const int RAS_MaxDeviceType = 16; 2       public const int RAS_MaxDeviceName = 128; 3       public const int MAX_PATH = 260; 4       public const int ERROR_BUFFER_TOO_SMALL = 603; 5       public const int ERROR_SUCCESS = 0; 6  7         [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Auto)] 8          public struct RASCONN 9 {10     public int dwSize;11     public IntPtr hrasconn;12     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxEntryName)]13     public string szEntryName;14     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxDeviceType)]15     public string szDeviceType;16     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxDeviceName)]17     public string szDeviceName;18     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]19     public string szPhonebook;20     public int dwSubEntry;21     public Guid guidEntry;22     public int dwFlags;23     public Guid luid;                                                    24 }25         [DllImport("rasapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]26         public static extern int RasEnumConnections(27             [In, Out] RASCONN[] rasconn,28             [In, Out] ref int cb,29             [Out] out int connections);30       public const int RAS_MaxEntryName = 256;31        //挂断拨号,断开网络链接32       [DllImport("rasapi32.dll", SetLastError = true)]33      public static extern uint RasHangUp(IntPtr hRasConn);34

函数部分就完成了,接下来我们可以这样写:

View Code
1  public void DisConnect() 2       { 3            System.Adsl.RASCONN[] connections = new System.Adsl.RASCONN[1];//创建新连接 4           connections[0].dwSize = Marshal.SizeOf(typeof(System.Adsl.RASCONN)); //未连接申请内存空间 5           int connectionCount = 0;//设置连接数 6           int cb = Marshal.SizeOf(typeof(System.Adsl.RASCONN));// 7           int ret = Adsl.RasEnumConnections(connections, ref cb, out connectionCount); 8            Adsl.RasHangUp(connections[0].hrasconn); 9              10       }

代码实在是很简单,一看就明白,因此没必要多啰嗦了,相信各位比我还在行。这个也就是很久以前就流行于网络的方法了。但是这样一个方法其实并不是总能兼容地跑在我们各种各样的机器上,很多电脑和网络环境其实都无法真正实现。

在这里干脆给大家添上上述功能实现的完整代码吧,以免被我说得思路更加不清晰了。^.^

View Code
1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Text;  5 using System.Runtime.InteropServices;  6   7 namespace System  8 {  9     ///  10     /// http://www.cnblogs.com/uu102 11     /// 凌晨的搜索者 12     ///  13    public class Adsl 14     { 15       public const int RAS_MaxDeviceType = 16; 16       public const int RAS_MaxDeviceName = 128; 17       public const int MAX_PATH = 260; 18       public const int ERROR_BUFFER_TOO_SMALL = 603; 19       public const int ERROR_SUCCESS = 0; 20  21         [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Auto)] 22          public struct RASCONN 23 { 24     public int dwSize; 25     public IntPtr hrasconn; 26     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxEntryName)] 27     public string szEntryName; 28     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxDeviceType)] 29     public string szDeviceType; 30     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxDeviceName)] 31     public string szDeviceName; 32     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)] 33     public string szPhonebook; 34     public int dwSubEntry; 35     public Guid guidEntry; 36     public int dwFlags; 37     public Guid luid;                                                     38 } 39         [DllImport("rasapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] 40         public static extern int RasEnumConnections( 41             [In, Out] RASCONN[] rasconn, 42             [In, Out] ref int cb, 43             [Out] out int connections); 44       public const int RAS_MaxEntryName = 256; 45        //挂断拨号,断开网络链接 46       [DllImport("rasapi32.dll", SetLastError = true)] 47      public static extern uint RasHangUp(IntPtr hRasConn); 48       49       [Flags] 50      public enum InternetDialFlags 51       { 52           INTERNET_DIAL_FORCE_PROMPT = 0x2000, 53           INTERNET_DIAL_SHOW_OFFLINE = 0x4000, 54           INTERNET_DIAL_UNATTENDED = 0x8000 55       } 56       [System.Runtime.InteropServices.DllImport("Wininet.dll")] 57       public  static extern Int32 InternetDial(IntPtr hwndParent, string lpszConnectoid, Int32 dwFlags, ref Int32 lpdwConnection, Int32 dwReserved); 58       public void DisConnect() 59       { 60            System.Adsl.RASCONN[] connections = new System.Adsl.RASCONN[1];//创建新连接 61           connections[0].dwSize = Marshal.SizeOf(typeof(System.Adsl.RASCONN)); //未连接申请内存空间 62           int connectionCount = 0;//设置连接数 63           int cb = Marshal.SizeOf(typeof(System.Adsl.RASCONN));// 64           int ret = Adsl.RasEnumConnections(connections, ref cb, out connectionCount); 65            Adsl.RasHangUp(connections[0].hrasconn); 66               67       } 68       public string AdslName { get; set; } 69       public string Uid { get; set; } 70       public string Pwd { get; set; } 71       public Adsl(string adslName, string uid, string pwd) 72       { 73           this.AdslName = adslName; 74           this.Uid = uid; 75           this.Pwd = pwd; 76  77       } 78       public System.Diagnostics.Process Connect() 79       { 80           /* int temp = 0; 81          Adsl.InternetDial(IntPtr.Zero, "", (int)Adsl.InternetDialFlags.INTERNET_DIAL_UNATTENDED, ref temp, 0);*/ 82           System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); 83           startInfo.FileName = "RasDial"; 84           if (string.IsNullOrEmpty(this.AdslName)) this.AdslName= "宽带连接"; 85           startInfo.Arguments = string.Format("{0} {1} {2}",this.AdslName,this.Uid,this.Pwd); 86           startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; 87           System.Diagnostics.Process process = System.Diagnostics.Process.Start(startInfo); 88           return process; 89       } 90       public System.Diagnostics.Process ReDial() 91       { 92           DisConnect(); 93          return  Connect(); 94       } 95      public static System.Diagnostics.Process ClearCookies(string cmd) 96       { 97           System.Diagnostics.Process p = new System.Diagnostics.Process(); 98           p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; 99           p.StartInfo.FileName = "RunDll32.exe";100           // 关闭Shell的使用101           p.StartInfo.UseShellExecute = false;102           // 重定向标准输入103           p.StartInfo.RedirectStandardInput = true;104           // 重定向标准输出105           p.StartInfo.RedirectStandardOutput = true;106           //重定向错误输出107           p.StartInfo.RedirectStandardError = true;108           p.StartInfo.CreateNoWindow = true;109 110           p.Start();111           p.StandardInput.WriteLine(cmd);112           p.StandardInput.WriteLine("exit");113           return p;114       }115 116 117 118 119     }120  121 }122

以上所述是PPPOE下连接方法,如果是路由器下的连接,则有很大不同,由于时间关系,下次再补充说说 路由器下自动更换IP的实现吧!

 

 

转载于:https://www.cnblogs.com/uu102/archive/2012/09/10/2679293.html

你可能感兴趣的文章
tensorflow saver简介+Demo with linear-model
查看>>
Luogu_4103 [HEOI2014]大工程
查看>>
Oracle——SQL基础
查看>>
项目置顶随笔
查看>>
Redis的安装与使用
查看>>
P1970 花匠
查看>>
java语言与java技术
查看>>
NOIP2016提高A组五校联考2总结
查看>>
iOS 项目的编译速度提高
查看>>
table中checkbox选择多行
查看>>
Magento开发文档(三):Magento控制器
查看>>
性能调优攻略
查看>>
ie6解决png图片透明问题
查看>>
瞬间的永恒
查看>>
2019-8-5 考试总结
查看>>
JS中实现字符串和数组的相互转化
查看>>
web service和ejb的区别
查看>>
Windows Azure Cloud Service (29) 在Windows Azure发送邮件(下)
查看>>
微信上传素材返回 '{"errcode":41005,"errmsg":"media data missing"}',php5.6返回
查看>>
div或者p标签单行和多行超出显示省略号
查看>>