实现拨号上网

来源:互联网 发布:nginx 图片不显示 编辑:程序博客网 时间:2024/04/28 22:07

 实现拨号上网
  
  本例知识要点:
  1. 远程访问服务(RAS)简介
  远程访问服务(Remote Access Service 简称RAS)是Windows 操作系统提供的系统服务之一,通过电话线可以使单独的计算机接入网络,或通过两个RAS对拨使两个局域网互连。此项服务的功能可以使远程的计算机端点以较低的费用同网络连接。
  由于Windows操作系统的大量使用,远程访问服务功能也被广泛应用,在许多具体的应用程序中,均已通过远程访问功能来实现对远程的资源共享等功能。连通远程访问服务,只要从远程客户机拨通拨号网络就可以了,执行挂断就结束连接,鼠标操作Windows 98中的拨号网络就可以直接连通和挂断。但有些时候我们希望在应用程序中RAS拨号和挂断对用户不可见,那么就需要相应的程序控制来实现RAS拨通和挂断。
  2. RasDial拨号函数
  Windows 98提供了API函数RasDial,调用系统中建好的拨号网络连接,完成RAS拨号,同时提供了API函数RasHangUp断开连接。RasDial的原型如下:
  DWORD RasDial(LPRASDIALEXTENSIONS lpRasDialExtensions,LPCTSTR lpszPhonebook,LPRASDIALPARAMS lpRasDialParams, DWORD dwNotifierType, LPVOID lpvNotifier, LPHRASCONN lphRasConn)
  函数的第三个参数为指向RASDIALPARAMS型结构体的指针,它提供了配置RAS拨号的参数:第五个参数为拨号完成后执行的回调函数;第六个参数是LPHRASCONN型指针,拨号连接建立好之后将返回此连接的句柄;其他三个参数为NULL即可。函数调用如果成功将返回零,否则返回错误代码,此错误代码的含义可以在头文件Raserror.h中找到。
  lpRasDialExtensions和lpszPhonebook:仅在Windows NT下有效,在Windows 95下,这两个参数被忽略。
  lpRasDialParams:这个参数很重要,它指向一个RASDIALPARAMS结构,RASDIALPARAMS型结构体包括7个数据成员:dwSize、szEntryName、szPhoneNumber、szCallNumber、szUserName、szPassWord和szDomain,分别解释如下:
  1) szSize:应设定为sizeof(RASDIALPARAMS)。
  2) szEntryName和szPhoneNumber:这两个参数有联系,szEntryName可以指定要建立的连接,比方说“我的连接”等等,“我的连接”是用户在Windows 98“拨号网络”里建立的连接。这时,Modem将拨打用户在“我的连接”中设定的ISP号码,此时szPhoneNumber成员设为空字符串“”即可:如果用户要在程序中自行指定要拨打的ISP号码的话,szEntryNumber可以设定为空字符串“”,此时应设置szPhoneNumber为你的ISP号码(163,169等)。
  3) szCallBackNumber,szDomain:设为空串“”即可。
  4) szUserName,szPassWord:登陆用户名和密码。如169公用guest。
  5) dwNotifierType:指定是窗口还是由回调函数来处理确认消息。通过确认消息用户可以得到RasDial过程的当前状态。如“正在打开端口”,“正在验证用户名和密码”等。也可设为NULL。
  6) dwNoifier:指定处理确认消息的窗口或回调函数,也可设为NULL。
  7) lphRasConn:指向一个类型为HRASCONN的变量。在调用RasDial前必须指定为NULL,RasDial若成功返回,则将RAS连接的句柄存放于它所指向的变量中。用户可以通过此句柄来断开连接。
  3. 拨号状态
  以指定窗口来处理确认消息为例,说明如何得到拨号过程的当前状态。
  在处理确认消息的对话框类(或视图类等)的实现代码中加入:
  Const UINT WM_RASEVENT = ::RegisterWindowMessageA(RASDIALEVENT)
  在Message Map中手工加入消息映射:CDialInfo是用户定义的对话框类名称。
  BEGIN_MESSAGE_MAP(CDialInfo, CDialog)
  //AFX_MSG_MAP
  ……
  ON_REGISTER_MESSAGE(WM_RASEVENT,OnRasDialEvent)//添加消息
  //AFX_MSG_MAP
  END_MESSAGE_MAP()
  加入成员函数处理消息:
  LRESULT CDialInfo::OnRasDialEvent(WPARAM wp,LPARAM lp)
  {
  RASCONNSTATE rasstate=(RASCONNSTATE)wp;
  //用ListBox控件(ID为IDC_BOHAOINFO)来显示拨号状态)
  CListBox *info=(CListBox *)GetDlgItem(IDC_BOHAOINFO)
  Switch(rasstate)
  {
  Case RASCS_OpenPort:
  Info->AddString(_T(“打开端口。。。。。。”));
  Break;
  Case RASCS_Opened:
  Info->AddString(_T(“端口已打开。”));
  Break;
  Case RASCS_ConnectDevice:
  Info->AddString(_T(“连接设备。。。。。。”));
  Break;
  Case RASCS_DeviceConnected:
  Info->AddString(_T(“设备已连接。”));
  Break;
  Case RASCS_Authenticate:
  Info->AddString(_T(“验证用户及密码”));
  Break;
  Case RASCS_Connected:
  Info->AddString(_T(“已连接”));
  Break;
  Case RASCS_Disconnected:
  Info->AddString(_T(“连接已断开”));
  Break;
  Default:
  Return (LRESULT)0;
  }
  }
  4. 断开连接
  由于定义了类型为HRASCONN的成员变量m_hRasConn来保存RAS连接的句柄。而且在调用RasDial时用指向m_hRasConn的指针作为lpRasConn参数。因此在拨号连接断开后应将m_hRasConn置为NULL。
  If(m_hRasConn!=NULL)
  {
  RasHangUp(m_hRasConn);
  m_hRasConn = NULL;
  ::Sleep(2000);
  }
  上述代码中的Sleep函数是必要的,它等待一定时间来断开连接。如果不等待一段时间,计算机有可能无法正常关闭端口。导致下一次无法拨号,只有重新启动Windows才能解决。
  
  
  本例制作过程
  1) 启动Microsoft Visual C++6.0,单击File下拉菜单下的“新建”命令,在“工程”标签下选择MFC AppWizard(exe)。
  2) 在“工程名”文本框中输入工程名Dialproc,在“位置”文本框中输入工程地址,单击OK按钮进入新建应用程序向导。
  3) 在向导第一步选择Dialog Based(对话框),如图11-1所示。第二到第四步接受默认设置。
  图11-1
  4) 单击“完成”按钮,单击项目工程区的类视图ResourceView,展开Dialog中的IDD_DIALPRO_DIALOG对话框,清除对话框中的所有控件,并用控件工具栏中的工具增加如图11-2所示的对话框。
  图11-2
  IDD_DIALPRO_DIALOG对话框中的控件分别是:
  文本框 标识:IDC_STATIC 标题:拨号连接
  组合框 标识:IDC_DIALUP_COMBO
  文本框 标识:IDC_STATIC 标题:用户
  编辑框 标识:IDC_USER_EDIT
  文本框 标识:IDC_STATIC 标题:密码
  编辑框 标识:IDC_PASSWORD_EDIT
  按钮 标识:IDC_CONNECT_BUTTON 标题:连接
  按钮 标识:IDCANCEL 标题:退出
  
  1.给新添加的控件增加成员变量
  1)给控件IDC_DIALUP_COMBO增加成员变量,按住Ctrl键并双击该控件,弹出Add Member Variable对话框,在Member Variable Name中输入m_DialCombo,Category列表框选择Control,如图11-3所示,单击OK按钮确认。
  图11-3
  2)给控件IDC_USER_EDIT增加成员变量,按住Ctrl键双击该控件,弹出Add Member Variable对话框,在Member Variable Name中输入m_UserID,Category列表框选择Control,如图11-4所示,单击OK按钮确认。
  图11-4
  3)给控件IDC_PASSWORD_EDIT增加成员变量,按住Ctrl键双击该控件,弹出Add Member Variable对话框,在Member Variable Name中输入m_Password,Category列表框选择Control,如图11-5所示,单击OK按钮确认。
  图11-5
  2.给类添加成员函数
  1)给类CDialprocDlg添加成员函数SetupDialupCombo()。
  在dialprocDlg.h增加成员函数SetupDialupCombo()的说明:
  #include <ras.h&gt;
  …
  Public:
  void SetupDialupCombo(void);
  …
  在dialprocDlg.cpp中编辑成员函数SetupDialupCombo()。
  Void CDialprocDlg::SetupDialupCombo()
  {
  DWORD n;
  DWORD dwSize=0;
  m_DialCombo.ResetContent();
  DWORD ret=RasEnumEntries(NULL,NULL,NULL,&dwSize, &amp;n);
  n=dwSize/sizeof(RASENTRYNAME);
  RASENTRYNAME *entry=new RASENTRYNAME[n];
  if(entry)
  {
  entry[0].dwSize=sizeof(RASENTRYNAME);
  DWORD ret=RasEnumEntries(NULL,NULL,entry,&amp;dwSize, &amp;n);
  for(DWORD i=0; i  {
  m_DialCombo.AddString(entry[i].szEntryName);
  }
  delete[] entry;
  }
  }
  
  2) 打开ClassWizard,Class Name选择CDialprocDlg,Object IDs 选择IDC_CONNECT_BUTTON,Messages 选择BN_CLICKED,单击Add Function按钮,在类CDialprocDlg增加成员函数OnConnectbutton();
  void CDialprocDlg::OnConnectButton()
  {
  //TODO:Add your control notification handler code here
  CWaitCursor wait;
  RASDIALPARAMS params;
  memset(¶ms,’/0’,sizeof(params));
  param.dwSize=sizeof(params);
  m_DialCombo.GetWindowText(params.szEntryName,sizeof(params.szEntryName)-1);
  strcpy(params.szPhoneNumber,””);
  m_UserID.GetWindowText(params.szUserName,sizeof(params.szUserName)-1);
  m_Password.GetWindowText(params.szPassword,sizeof(params.szPassword)-1);
  HRASCONN handle;
  if(RasDial(NULL,NULL,¶ms,NULL,NULL,&amp;handle)==0){
  MessageBox(“已经连接成功,按确定将切断电话”);
  }
  else
  {
  MessageBox(“您拨的计算机没有应答,请稍候再拨”);
  }
  wait.Restore();
  RasHangUp(handle);
  }
  
  3) 打开ClassWizard,Class Name选择CDialprocDlg,Object IDs 选择IDC_DIALUP_COMBO,Messages 选择CBN_SELCHANGE,单击Add Function按钮,在类CDialprocDlg增加成员函数OnSelchangeDialupCombo();
  
  void CDialprocDlg::OnSelchangeDialupCombo ()
  {
  //TODO:Add your control notification handler code here
  RASDIALPARAMS params;
  int sel;
  memset(¶ms,’/0’,sizeof(params));
  params.dwSize=sizeof(RASDIALPARAMS);
  sel=m_DialCombo.GetCurSel();
  
  if(sel&gt;=0){
  m_DialCombo.GetLBText(sel,params.szEntryName);
  TRACE(“%s/n”,params.szEntryName);
  BOOL p;
  RasGetEntryDialParams(NULL,¶ms,&amp;p);
  m_UserID.SetWindowText(params.szUserName);
  m_Password.SetWindowText(params.szPassword);
  }
  
  4) 打开ClassWizard,Class Name选择CDialprocDlg,Object IDs 选择CDialprocDlg,Messages 选择CBN_SELCHANGE,单击Add Function按钮,在类CDialprocDlg自动增加成员函数OnInitDialog();
  BOOL CDialprocDlg:;OnInitDialog()
  {
  CDialog::OnInitDialog();
  
  //Add”About….”menu item to system menu.
  //IDM_ABOUTBOX must be in the system command range.
  ASSERT((IDM_ABOUTBOX&amp;0xFFF0)==IDM_ABOUTBOX);
  ASSERT((IDM_ABOUTBOX&lt;0xF000); &lt;br &gt;  
  CMenu *pSysMenu = GetSystemMenu(FALSE);
  
  if(pSysMenu!=NULL)
  {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  
  if(!strAboutMenu.IsEmpty())
  {
  pSysMenu-&gt;AppendMenu(MF_SEPARATOR);
  pSysMenu-&gt;AppendMenu(MF_STRING,IDM_ABOUTBOX, strAboutMenu);
  }
  }
  
  //Set the icon for this dialog. The framework does this automatically
  //when the application’s main window is not a dialog
  SetIcon(m_hIcon, TRUE); //set big icon
  SetIcon(m_hIcon, FALSE); //set small icon
  
  // TODO:Add extra initialization here
  SetupDialupCombo();
  
  return TRUE; //return FALSE unless you set the focus to the control
  }
  
  3. 增加rasapi32.lib, 单击Project菜单,选择Setting,弹出Project Settings对话框,在Settings 对话框中选择Link选项,在Object/Library modules中键入rasapi32.lib,如图11-6 所示。
  
  图11-6
  单击Build下拉菜单的Excute dialproc.exe命令编译执行文件,就可以在组合框中选择机器上已有的连接进行拨号上网了。
  
  
  
  Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1681526

本文转自
http://blog.csdn.net/dehuadeng/archive/2007/07/06/1681526.aspx

原创粉丝点击