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

Windows 應用程式中實作 RAS 撥號與掛斷控制

     編輯:關於C++

前言

遠端存取服務(RAS)是 Windows NT 系統提供的網路服務,讓獨立電腦透過電話線接入網路,或兩地 LAN 互連。雖然使用者可手動操作「撥號網路」,但應用程式若需背景自動撥號/掛斷且對使用者不可見,則必須呼叫 Windows API 實作。本文說明 RasDial、RasHangUp 核心函數用法與完整 VC 範例。

一、核心 API 函數

RasDial - 建立撥號連線

DWORD RasDial(
    LPRASDIALEXTENSIONS lpRasDialExtensions,  // 擴充參數,通常 NULL
    LPCTSTR lpszPhonebook,                    // 電話簿路徑,NULL 為預設
    LPRASDIALPARAMS lpRasDialParams,          // 關鍵:撥號參數結構
    DWORD dwNotifierType,                     // 通知類型,0 為同步
    LPVOID lpvNotifier,                       // 回呼函數指標
    LPHRASCONN lphRasConn                     // 輸出:連線控制代碼
);
  • 成功回傳 0,失敗回傳錯誤碼(參考 Raserror.h)
  • 第 3 參數 RASDIALPARAMS 包含所有撥號設定
  • 第 5 參數可指定回呼函數監控撥號狀態
  • 第 6 參數回傳 HRASCONN,掛斷時需用到

RasHangUp - 斷開連線

DWORD RasHangUp(HRASCONN hRasConn);
  • 參數為 RasDial 回傳的連線控制代碼
  • 成功回傳 0

二、RASDIALPARAMS 結構體詳細欄位

成員型別說明
dwSizeDWORD結構體大小,必須填 sizeof(RASDIALPARAMS)
szEntryNameTCHAR[]撥號連線名稱(電話簿中的項目名)
szPhoneNumberTCHAR[]撥打電話號碼
szCallbackNumberTCHAR[]回呼電話號碼
szUserNameTCHAR[]登入使用者名稱
szPasswordTCHAR[]登入密碼
szDomainTCHAR[]登入網域

三、回呼函數原型

VOID WINAPI RasDialFunc(
    UINT unMsg,           // 訊息類型
    RASCONNSTATE state,   // 目前連線狀態
    DWORD dwError         // 錯誤碼
);

可在回呼中更新 UI 顯示進度、處理錯誤或記錄日誌。

四、完整 VC 實作範例

專案設定

  1. 專案 Settings → Link 加入 Rasapi32.lib 靜態庫
  2. 包含標頭:#include <ras.h> #include <raserror.h>
  3. 建立對話方塊,放置「撥號」與「掛斷」兩個按鈕

全域變數宣告

HRASCONN g_hRasConn = NULL;  // 連線控制代碼

撥號按鈕處理

void OnDialClick() {
    RASDIALPARAMS rdParams = {0};
    rdParams.dwSize = sizeof(RASDIALPARAMS);
    _tcscpy(rdParams.szEntryName, _T("dial"));      // 連線項目名
    _tcscpy(rdParams.szPhoneNumber, _T("22"));      // 內部分機號
    _tcscpy(rdParams.szCallbackNumber, _T("*"));
    _tcscpy(rdParams.szUserName, _T("dial"));
    rdParams.szPassword[0] = _T('\0');              // 無密碼
    _tcscpy(rdParams.szDomain, _T("dial"));

    g_hRasConn = NULL;
    DWORD dwRet = RasDial(NULL, NULL, &rdParams, 0L, 
                          (RASDIALFUNC)RasDialFunc, &g_hRasConn);
    if (dwRet != 0) {
        // 錯誤處理:可用 RasGetErrorString 取得訊息
        TCHAR buf[256];
        RasGetErrorString(dwRet, buf, 256);
        AfxMessageBox(buf);
    }
}

回呼函數實作

VOID WINAPI RasDialFunc(UINT unMsg, RASCONNSTATE state, DWORD dwError) {
    // 可根據 state 更新進度條、顯示狀態文字
    // 常見狀態:RASCS_OpenPort, RASCS_PortOpened, RASCS_ConnectDevice, 
    // RASCS_DeviceConnected, RASCS_Authenticate, RASCS_Authenticated, 
    // RASCS_Connected(成功)
    if (dwError != 0) {
        // 記錄錯誤
    }
}

掛斷按鈕處理

void OnHangUpClick() {
    if (g_hRasConn) {
        DWORD dwRet = RasHangUp(g_hRasConn);
        if (dwRet != 0) {
            // 錯誤處理
        }
        g_hRasConn = NULL;
    }
}

五、關鍵實作細節與注意事項

  • 電話簿項目:szEntryName 必須與「撥號網路」中建立的連線名稱完全一致
  • 同步 vs 非同步:範例使用同步模式(dwNotifierType=0),UI 會阻塞至撥號完成;生產環境建議用非同步模式配合回呼
  • 錯誤代碼查詢:使用 RasGetErrorString 將錯誤碼轉為可讀訊息
  • 多執行緒安全:HRASCONN 應妥善保存,避免多執行緒同時操作同一連線
  • 資源釋放:程式結束前務必檢查並掛斷殘留連線

六、適用場景

  • 自動備份軟體:排程撥號上傳資料
  • 遠端監控系統:定期撥號回報狀態
  • 行動應用同步:背景同步資料無需使用者干預
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved