首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC++

VC++ 實作撥號上網程式完整指南

     編輯:VC++

前言

在 NetAnts、Download Expert 等下載工具中,都內建了定時撥號上網的功能。對於一般使用者而言,撥號上網主要仰賴 Windows 的遠程存取服務。本文將詳細介紹如何在 Visual C++ 環境下,運用 RAS API 實作撥號連線功能。

核心 API:RasDial 函式

Visual C++ 提供了 ras.h 標頭檔,其中宣告了 RAS API。實作撥號上網的關鍵在於 RasDial 函式,其原型如下:

DWORD RasDial(
  LPRASDIALEXTENSIONS lpRasDialExtensions,
  LPCTSTR lpszPhonebook,
  LPRASDIALPARAMS lpRasDialParams,
  DWORD dwNotifierType,
  LPVOID lpvNotifier,
  LPHRASCONN lphRasConn
);

關鍵參數說明

  • lpRasDialExtensions、lpszPhonebook:僅在 Windows NT 下有效,Windows 95/98 會忽略。
  • lpRasDialParams:指向 RASDIALPARAMS 結構,包含連線名稱、電話號碼、使用者名稱、密碼等資訊。
    • dwSize:設為 sizeof(RASDIALPARAMS)
    • szEntryName 與 szPhoneNumber:若指定連線名稱(如「我的連線」),電話號碼可留空;若直接指定號碼,連線名稱留空,電話號碼填入 ISP 號碼(如 169、663)。使用 201 電話卡時,格式為 201,,,帳號,密碼#,ISP號碼#(逗號代表暫停)。
    • szUserName、szPassword:登入帳密,如 169 共用帳號 guest/guest。
  • dwNotifierType、dwNotifier:指定視窗或回呼函式處理狀態通知,可設為 NULL。
  • lphRasConn:指向 HRASCONN 變數,呼叫前必須設為 NULL,成功後會儲存連線控制代碼,供後續斷線使用。

處理撥號狀態通知

透過註冊視窗訊息 WM_RASEVENT,即可即時取得撥號過程狀態。在對話方塊類別中加入:

const UINT WM_RASEVENT = ::RegisterWindowMessageA(RASDIALEVENT);

於訊息對應表加入:

ON_REGISTERED_MESSAGE(WM_RASEVENT, OnRasDialEvent)

實作處理函式:

LRESULT CMyDialog::OnRasDialEvent(WPARAM wp, LPARAM lp)
{
    RASCONNSTATE rasstate = (RASCONNSTATE)wp;
    CListBox* pList = (CListBox*)GetDlgItem(IDC_INFOLIST);
    
    switch (rasstate)
    {
        case RASCS_OpenPort:      pList->AddString(_T("開啟連接埠...")); break;
        case RASCS_PortOpened:    pList->AddString(_T("連接埠已開啟")); break;
        case RASCS_ConnectDevice: pList->AddString(_T("連接裝置...")); break;
        case RASCS_DeviceConnected: pList->AddString(_T("裝置已連接")); break;
        case RASCS_Authenticate:  pList->AddString(_T("驗證帳號密碼")); break;
        case RASCS_Authenticated: pList->AddString(_T("驗證通過")); break;
        case RASCS_Connected:     pList->AddString(_T("已連線")); break;
        case RASCS_Disconnected:  
            pList->AddString(_T("連線已中斷"));
            m_hRasConn = NULL; // 重設連線控制代碼
            break;
    }
    return 0;
}

斷開連線

使用 RasHangUp 並搭配等待機制,避免連接埠未正確關閉導致下次無法撥號:

if (m_hRasConn != NULL)
{
    RasHangUp(m_hRasConn);
    m_hRasConn = NULL;
    Sleep(2000); // 必須等待,否則可能導致連接埠殘留
}

更穩健的作法是輪詢 RasGetConnectStatus 直到傳回 ERROR_INVALID_HANDLE:

RASCONNSTATUS rStatus;
while (RasGetConnectStatus(m_hRasConn, &rStatus) != ERROR_INVALID_HANDLE)
{
    ::Sleep(0);
}

取得現有連線控制代碼

當瀏覽器停止回應或需重新執行程式控制連線時,可用 RasEnumConnections 列舉現有連線:

HRASCONN hRasConnect;
DWORD dwBufferSize, dwNumConnections;
LPRASCONN lpRasConn = new RASCONN[3];
lpRasConn[0].dwSize = sizeof(RASCONN);
dwBufferSize = 3 * sizeof(RASCONN);

if (RasEnumConnections(lpRasConn, &dwBufferSize, &dwNumConnections) == 0)
{
    for (DWORD i = 0; i < dwNumConnections; i++)
    {
        hRasConnect = lpRasConn[i].hrasconn;
        RasHangUp(hRasConnect);
        ::Sleep(2000);
    }
}
delete[] lpRasConn;

結語

至此,一個基本的撥號上網程式已完成。若需深入了解伺服器端程式設計,請參考 MSDN Platform SDK 中的 Remote Access Service 文件。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved