VC 创建拨号连接A

首先是用ICMP检查网络是否连通:

bool   Util::CheckInternet()
{
    
  char     *  SendData   =     "  Data Buffer  "  ;
    LPVOID ReplyBuffer;
    DWORD dwRetVal;
    HANDLE hIcmpFile;
    
  bool   b  =  false  ;
    
  if   ((hIcmpFile   =   IcmpCreateFile())   ==   INVALID_HANDLE_VALUE)
        
  return     false  ;

    ReplyBuffer 
  =   (VOID  *  ) malloc(  sizeof  (ICMP_ECHO_REPLY)   +     sizeof  (SendData));
    
  if   ((dwRetVal   =   IcmpSendEcho(hIcmpFile, 
        inet_addr(
  "  209.131.36.158  "  ), //用的雅虎的一个IP,可能延迟会大一点,用国内的会小一点
        SendData, 
  sizeof  (SendData), 
        NULL, ReplyBuffer, 
        
  sizeof  (ReplyBuffer)   +     sizeof  (ICMP_ECHO_REPLY),
        
  1000  ))   !=     0  ) {
        b
  =  true  ;
    }
    free(ReplyBuffer);
    
  return   b;
}

很简单的几行代码,没有注释;
如果网络不通的话枚举拨号连接,进行拨号:

bool   RASManager::ConnectNetwork()
{
    RASENTRYNAME Entries[
  15  ];   
    DWORD cb,cEntries,dwRet;   
    Entries[
  0  ].dwSize  =  sizeof  (RASENTRYNAME);   
    cb
  =  sizeof  (Entries);   
    cEntries
  =  0  ;   
    
    dwRet
  =  ::RasEnumEntries(NULL, NULL,   &  Entries[  0  ],   &  cb,   &  cEntries);  //  如果函数成功,则返回0    
    
    
  if  (dwRet   ==     0  )   
    {
        CHAR  szRasEntryName[RAS_MaxEntryName 
  +     1  ]  =  {  0  };
        
  for  (UINT i  =  0  ;i  <  cEntries;i  ++  )
            strcpy(szRasEntryName,Entries[i].szEntryName);
        RASDIALPARAMS rdParams;
        DWORD dwRet;
        hConn
  =  NULL;
        rdParams.dwSize
  =  sizeof  (RASDIALPARAMS);
        strcpy(rdParams.szEntryName,szRasEntryName);
        strcpy(rdParams.szPhoneNumber,
  "  #777  "  );  //  我用的3G卡,拨#777号码 
        strcpy(rdParams.szUserName,  "  用户名  "  );
        strcpy(rdParams.szPassword,
  "  密码  "  );
        strcpy(rdParams.szDomain,"");//这个也很重要,指定域,如果不指定这个的话下面注释的两句一定要加上,下边两句的意思是获取最后一次连接成功时的参数信息,如果用下边两句的话连同这行和这行上面的三行都可以省略
       // BOOL fPass;
        //RasGetEntryDialParams(NULL, 
  &  rdParams,  &  fPass);
        dwRet
  =  RasDial(NULL,NULL,  &  rdParams,  0L  ,NULL,  &  hConn);
        
  if  (dwRet  !=  0  )
        {
            
  return     false  ;
        }
        
  return     true  ;
    }    
    
  else      
    {    
        
  return     false  ;
    }
}

预先建立拨号连接,以上拨号代码经过修改已经不需要保存密码,只建立一个拨号连接即可。Windows XP or later:   Do not use the RasSetEntryDialParams function. MSDN上面的说法就是RasSetEntryDialParams 别在XP之后的系统上使用了。
检查拨号连接的状态,如果已经通过拨号连接上了网络当然不用再进行拨号了,代码如下:

bool   RASManager::RasGetConnectStatus()
{
    LPRASCONN lpRasConn 
  =   NULL;    
    DWORD   cbBuf   
  =       0  ;    
    DWORD   cConn   
  =       0  ;    
    DWORD   dwRet   
  =       0  ;    
    HRASCONN  hrasconn;
    
  bool      bResult  =  FALSE;
    RASCONNSTATUS rasStatus;    
    UINT   ndx;
    cbBuf 
  =     sizeof  (RASCONN);
    lpRasConn 
  =   (LPRASCONN)malloc((UINT)cbBuf);  
    
  if   (lpRasConn   !=   NULL)
    {    
        lpRasConn
  ->  dwSize   =     sizeof  (RASCONN);    
        dwRet 
  =   RasEnumConnections(lpRasConn,  &  cbBuf,  &  cConn);  
        
  for  (ndx  =  0  ;ndx  <  cConn;ndx  ++  )      
        {
            hrasconn 
  =   lpRasConn[ndx].hrasconn;            
            rasStatus.dwSize 
  =     sizeof  (RASCONNSTATUS);
            dwRet 
  =   ::RasGetConnectStatus(hrasconn,  &  rasStatus);
            
  if  (dwRet)    
                bResult
  =  FALSE;    
            
  else 
            {    
                
  if  (rasStatus.rasconnstate   ==   RASCS_Connected)    
                    bResult
  =  TRUE;    
                
  else 
                    bResult
  =  FALSE;    
            }
        }
    }
    
  else 
        bResult
  =  FALSE;
    free(lpRasConn);
    
  return   bResult;
}

以上判断是如果检查到有一个已经连接的拨号连接就返回了,应该不会有两个或者以上的拨号连接同时连接,打开端口会失败的。
还有一个是断线:

void   RASManager::HungUP()
{
    LPRASCONN lpRasConn
  =  NULL;
    DWORD   cbBuf 
  =     0  ;
    DWORD   cConn 
  =     0  ;
    DWORD   dwRet 
  =     0  ;
    HRASCONN   hrasconn;
    RASCONNSTATUS rasStatus;
    UINT   ndx;
    
    cbBuf 
  =     sizeof  (RASCONN);
    lpRasConn 
  =   (LPRASCONN)malloc((UINT)cbBuf);
    
  if  (lpRasConn   !=   NULL)
    {
        lpRasConn
  ->  dwSize   =     sizeof  (RASCONN);    
        dwRet 
  =   RasEnumConnections(lpRasConn,  &  cbBuf,  &  cConn);  
        
        
  for  (ndx  =  0  ;ndx  <  cConn;ndx  ++  )
        {
            hrasconn 
  =   lpRasConn[ndx].hrasconn;
            rasStatus.dwSize 
  =     sizeof  (RASCONNSTATUS);
            dwRet 
  =   ::RasGetConnectStatus(hrasconn,  &  rasStatus);
            
  if  (  !  dwRet)
            {
                
  if  (rasStatus.rasconnstate   ==   RASCS_Connected)
                    RasHangUp(hrasconn);
            }
        }
        free(lpRasConn);
    }
}

这个没什么好说的,执行关闭拨号连接的操作。
用程序创建连接,经过修改,已经可以正常创建连接,代码如下:

bool   RASManager::CreateRASLink()
{
    LPRASENTRY lpRasEntry 
  =   NULL;
    DWORD cb 
  =     sizeof  (RASENTRY);
    DWORD dwBufferSize 
  =     0  ;
    DWORD dwRet 
  =     0  ;
    
    
    
  //   取得entry的大小,这句也不知道是不是必须的,因为sizeof(RASENTRY)和这里取到的dwBufferSize是一样的,不过还是Get一下安全点 
    RasGetEntryProperties(NULL,  ""  , NULL,   &  dwBufferSize, NULL, NULL); 
    
  if   (dwBufferSize   ==     0  )
        
  return     false  ;
    
    lpRasEntry 
  =   (LPRASENTRY)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
    
  if   (lpRasEntry   ==   NULL)
        
  return     false  ;
    
    ZeroMemory(lpRasEntry, 
  sizeof  (RASENTRY));
    lpRasEntry
  ->  dwSize   =   dwBufferSize;
    lpRasEntry
  ->  dwfOptions   =  RASEO_RemoteDefaultGateway|RASEO_PreviewPhoneNumber|RASEO_PreviewUserPw;   //  这里的几个选项挺重要的,  RASEO_RemoteDefaultGateway这个选项把创建的连接设置为默认连接,  RASEO_PreviewPhoneNumber 对应选项中的提示输入电话号码, RASEO_PreviewUserPw对应选项中的提示用户名和密码 
    lpRasEntry  ->  dwType   =   RASET_Phone;
    
    lstrcpy(lpRasEntry
  ->  szDeviceType, RASDT_Modem);
    lstrcpy(lpRasEntry
  ->  szDeviceName,  "  www  "  );
    lpRasEntry
  ->  dwfNetProtocols   =   RASNP_Ip;
    lpRasEntry
  ->  dwFramingProtocol   =   RASFP_Ppp;
    
    dwRet 
  =   RasSetEntryProperties(NULL,   "  www  "  , lpRasEntry, dwBufferSize, NULL,   0  );   //   创建连接 
//
 The  RasSetEntryProperties function changes the connection information for an entry in the phone book or creates a new phone-book entry.(reference MSDN)
    HeapFree(GetProcessHeap(),   0  , (LPVOID)lpRasEntry);
    
    
  if   (dwRet   !=     0  )
        
  return     false  ;
    
  return     true  ;
}

上面的代码到是可以创建一个拨号连接,不过是个空的,里面没用用户名和密码等信息,需要用上面的拨号代码来指定拨号参数,不能使用RasGetEntryDialParams来获取了。 
上面的代码基本上是在网络上搜索所得,稍加修改,在这里整理一下。

再补充一下删除连接的操作,代码如下:

void   RASManager::DeletePhoneBookEntry()
{
    RASENTRYNAME Entries[
  15  ];   
    DWORD cb,cEntries,dwRet;
    Entries[
  0  ].dwSize  =  sizeof  (RASENTRYNAME);   
    cb
  =  sizeof  (Entries);
    cEntries
  =  0  ;   
    
    dwRet
  =  ::RasEnumEntries(NULL, NULL,   &  Entries[  0  ],   &  cb,   &  cEntries);  //  如果函数成功,则返回0    
    
    
  if  (dwRet   ==     0  )   
    {
        CHAR  szRasEntryName[RAS_MaxEntryName 
  +     1  ]  =  {  0  };
        
  for  (UINT i  =  0  ;i  <  cEntries;i  ++  )
        {
            strcpy(szRasEntryName,Entries[i].szEntryName);
            RasDeleteEntry(NULL,szRasEntryName);
        }
    }
}

要想实现自动启动拨号网络,就要使用 Remote Access Service (RAS) API,这个API最早是在Windows for Workgroup 3.11中出现的,现在它已经成为Win32 API的一个组成部分。该API将整个拨号网络称为Phonebook,而每一个连接称为PhonebookEntry。你可以使用 RasCreatePhonebookEntry来创建新的连接,用RasDial来拨号,而RasEnumEntries可以获得当前系统已有的所有连 接,使用其它的RAS函数还可以获取或设置连接的参数。 RasEditPhonebookEntry函数将激活标准的Windows 95/NT属性对话框来修改连接的属性。你可以从Win32 API的手册找到所有相关函数的详细介绍。

补充:在windows中一个拨号连接即为一个PhonrbookEntry以下称为电话薄记录或是连接。总的这些称为Phonebook。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值