福建師范大學(xué)社會(huì)學(xué)系 許春漫 ---- 本 文 提 出 采 用Win98 撥 號(hào) 網(wǎng) 絡(luò) 服 務(wù) 器、FTP 協(xié) 議 和 免 費(fèi) 個(gè) 人 主 頁(yè) 空 間 站 點(diǎn) 實(shí) 現(xiàn) 控 制 遠(yuǎn) 程 計(jì) 算 機(jī) 撥 號(hào) 上 網(wǎng) 并 獲 取 其IP 地 址 的 方 法, 該 方 法 在 實(shí) 施 遠(yuǎn) 程 維 護(hù) 等 方 面 具 有 較 高 的 實(shí) 用 價(jià) 值。
一、 問 題 的 提 出 ----許 多 計(jì) 算 機(jī) 系 統(tǒng) 需 要7 ×24 小 時(shí) 穩(wěn) 定 可 靠 運(yùn) 行, 當(dāng) 出 現(xiàn) 突 發(fā) 事 件 時(shí), 要 求 能 對(duì) 系 統(tǒng) 實(shí) 施 遠(yuǎn) 程 系 統(tǒng) 維 護(hù) 以 便 排 除 故 障, 此 時(shí) 就 需 要 本 地 計(jì) 算 機(jī) 和 遠(yuǎn) 程 系 統(tǒng) 建 立 通 信 連 接, 通 過 相 應(yīng) 的 工 具 軟 件 實(shí) 施 遠(yuǎn) 程 維 護(hù)。 在 建 立 遠(yuǎn) 程 通 信 連 接 時(shí), 通 常 采 用Modem 撥 號(hào) 方 法 將 遠(yuǎn) 端Modem 置 為 自 動(dòng) 應(yīng) 答 方 式, 由 本 地Modem 通 過 公 用 電 話 網(wǎng) 發(fā) 起 呼 叫 來(lái) 建 立 通 信 連 接。 當(dāng) 主、 被 叫Modem 所 在 地 之 間 的 長(zhǎng) 途 費(fèi) 率 較 高 時(shí), 經(jīng) 常 的 遠(yuǎn) 程 維 護(hù) 將 帶 來(lái) 較 高 的 長(zhǎng) 途 話 費(fèi) 開 支。 本 文 提 出 通 過Internet 建 立 兩 臺(tái) 計(jì) 算 機(jī) 之 間 通 信 的 方 法。 二、 通 知 遠(yuǎn) 程 計(jì) 算 機(jī) 撥 號(hào) 上 網(wǎng) ----遠(yuǎn) 程 計(jì) 算 機(jī) 安 裝Win98 操 作 系 統(tǒng), 在 安 裝 了 撥 號(hào) 網(wǎng) 絡(luò) 服 務(wù) 器 組 件 后, 便 可 配 置 為 一 臺(tái) 撥 號(hào) 網(wǎng) 絡(luò) 服 務(wù) 器, 供 本 地 計(jì) 算 機(jī) 通 過 電 話 網(wǎng) 撥 號(hào) 建 立 通 信 連 接, 并 訪 問 遠(yuǎn) 程 計(jì) 算 機(jī) 上 的 共 享 資 源。 在 撥 號(hào) 通 信 鏈 路 上 可 綁 定TCP/IP 等 通 信 協(xié) 議,Win98 撥 號(hào) 服 務(wù) 器 給 每 個(gè) 撥 入 計(jì) 算 機(jī) 分 配 一 個(gè) 獨(dú) 立 的IP 地 址, 同 時(shí) 也 給 自 身 分 配 一 個(gè)IP 地 址, 這 些IP 地 址 具 有 相 同 的 網(wǎng) 絡(luò) 編 號(hào), 同 屬 于 一 個(gè) 通 信 子 網(wǎng), 服 務(wù) 器 的 主 機(jī) 編 號(hào) 為1, 撥 入 計(jì) 算 機(jī) 的 主 機(jī) 編 號(hào) 依 次 從2 開 始 編 起。 另 外,Win98 撥 號(hào) 服 務(wù) 器 還 提 供 了 密 碼 保 護(hù) 功 能, 撥 入 計(jì) 算 機(jī) 只 有 在 提 供 正 確 的 密 碼 情 況 下, 才 能 成 功 建 立 起 撥 號(hào) 連 接。 ----當(dāng) 本 地 計(jì) 算 機(jī) 要 通 知 遠(yuǎn) 程 計(jì) 算 機(jī) 撥 號(hào) 登 錄Internet 時(shí), 首 先 通 過 電 話 撥 號(hào) 和 遠(yuǎn) 程 計(jì) 算 機(jī) 建 立 撥 號(hào) 連 接, 獲 取 遠(yuǎn) 程 計(jì) 算 機(jī) 分 配 給 本 機(jī) 的IP 地 址, 并 經(jīng) 處 理 得 到 遠(yuǎn) 程 計(jì) 算 機(jī) 的IP 地 址, 然 后, 和 遠(yuǎn) 程 計(jì) 算 機(jī) 建 立TCP/IP 連 接, 并 送 出 命 令 通 知 遠(yuǎn) 程 計(jì) 算 機(jī) 準(zhǔn) 備 斷 開 撥 號(hào) 連 接, 登 錄Internet, 當(dāng) 本 地 計(jì) 算 機(jī) 收 到 遠(yuǎn) 程 計(jì) 算 機(jī) 確 認(rèn) 信 息 后, 便 可 中 斷 和 遠(yuǎn) 程 計(jì) 算 機(jī) 的 撥 號(hào) 連 接, 也 準(zhǔn) 備 登 錄Internet。
三、 獲 取 遠(yuǎn) 程 計(jì) 算 機(jī)Internet IP 地 址 ----在 取 得 遠(yuǎn) 程 計(jì) 算 機(jī)Internet IP 地 址 前, 本 地 計(jì) 算 機(jī) 是 無(wú) 法 通 過Internet 和 遠(yuǎn) 程 計(jì) 算 機(jī) 進(jìn) 行 實(shí) 時(shí) 通 信 的。 遠(yuǎn) 程 計(jì) 算 機(jī) 登 錄Internet, 獲 取 動(dòng) 態(tài)IP 地 址 后, 可 通 過 發(fā) 電 子 郵 件 方 式 將 動(dòng) 態(tài)IP 地 址 通 知 本 地 計(jì) 算 機(jī), 也 可 通 過 將 動(dòng) 態(tài)IP 地 址 保 存 在 遠(yuǎn) 程、 本 地 計(jì) 算 機(jī) 都 可 訪 問 到 的FTP 服 務(wù) 器 文 件 中, 供 本 地 計(jì) 算 機(jī) 讀 取。 本 文 采 用 后 一 種 方 法, 若 沒 有 合 適 的FTP 服 務(wù) 器, 可 到 提 供 免 費(fèi) 主 頁(yè) 空 間 允 許 以FTP 方 式 維 護(hù) 的Web 站 點(diǎn) 上 申 請(qǐng) 一 塊 空 間, 供 遠(yuǎn) 程、 本 地 計(jì) 算 機(jī) 共 同 訪 問。 ----本 地 計(jì) 算 機(jī) 登 錄Internet 后, 用FTP 協(xié) 議 讀 取 指 定FTP 服 務(wù) 器 上 含 有 遠(yuǎn) 程 計(jì) 算 機(jī) 動(dòng) 態(tài)IP 地 址 的 文 本 文 件, 從 而 取 得 遠(yuǎn) 程 計(jì) 算 機(jī) 的Internet IP 地 址, 然 后, 本 地 計(jì) 算 機(jī) 便 可 通 過 Internet 和 遠(yuǎn) 程 計(jì) 算 機(jī) 啟 動(dòng) 任 何 基 于TCP/IP 連 接 的 通 信 應(yīng) 用 程 序, 如 利 用Pcanywhere 控 制 遠(yuǎn) 程 計(jì) 算 機(jī), 并 可 通 過 遠(yuǎn) 程 計(jì) 算 機(jī) 訪 問 與 遠(yuǎn) 程 計(jì) 算 機(jī) 相 連 的 整 個(gè) 網(wǎng) 絡(luò) 資 源, 達(dá) 到 對(duì) 遠(yuǎn) 程 計(jì) 算 機(jī) 系 統(tǒng) 進(jìn) 行 維 護(hù) 的 目 的。
四、 通 知 遠(yuǎn) 程 計(jì) 算 機(jī) 斷 開Internet 連 接 ---- 當(dāng) 本 地 計(jì) 算 機(jī) 和 遠(yuǎn) 程 計(jì) 算 機(jī) 通 信 結(jié) 束 后, 便 可 通 知 遠(yuǎn) 程 計(jì) 算 機(jī) 斷 開Internet 連 接。 利 用 遠(yuǎn) 程 計(jì) 算 機(jī) 的 Internet IP 地 址, 本 地 計(jì) 算 機(jī) 和 遠(yuǎn) 程 計(jì) 算 機(jī) 建 立TCP/IP 連 接, 送 出 斷 開Internet 指 令, 遠(yuǎn) 程 計(jì) 算 機(jī) 收 到 指 令 后, 回 送 確 認(rèn) 消 息, 斷 開 Internet 連 接, 等 待 下 一 個(gè) 命 令 的 到 來(lái)。 五、 程 序 實(shí) 現(xiàn) ----本 地、 遠(yuǎn) 程 計(jì) 算 機(jī) 運(yùn) 行 的 是 同 一 道 程 序, 通 過 不 同 的 命 令 按 鈕 來(lái) 激 活 本 地、 遠(yuǎn) 程 計(jì) 算 機(jī) 程 序 所 具 有 的 不 同 功 能。 程 序 采 用VC + +6.0 編 寫, 在Win98 環(huán) 境 下 調(diào) 試 運(yùn) 行 通 過。 限 于 篇 幅, 下 面 只 給 出 程 序 的 主 要 部 分 及 注 釋 說(shuō) 明, 并 省 去 了 一 些 出 錯(cuò) 處 理 環(huán) 節(jié)。 // 宏 定 義 #define MAX_PENDING_CONNECTS 2 #define NO_FLAGS_SET 0 #define MY_MSG_LENGTH 100 // 全 局 變 量 HRASCONN hCon; //RAS 連 接 句 柄 HWND hWin; HINSTANCE hInst; DWORD ThreadId=0; HANDLE hThread=NULL; char cRemoteIP[50]; //remote IP 地 址 SOCKET serv_sock,rsock; // 服 務(wù) 端 // 建 立 撥 號(hào) 連 接 函 數(shù), 成 功 返 回 TRUE else FALSE // szEntry 撥 號(hào) 連 接 名 szPhone 電 話 號(hào) 碼 szUser 和szPassword 分 別 為internet 的 用 戶 名 和 口 令 BOOL StartCon( HWND hWnd,char * szEntry,char * szUser,char * szPassword,char * szPhone ) { RASDIALPARAMS rdParams; DWORD dwRet; char szBuf[300]; rdParams.dwSize = sizeof(RASDIALPARAMS); lstrcpy(rdParams.szEntryName,szEntry); strcpy(rdParams.szPhoneNumber,szPhone); rdParams.szCallbackNumber[0] = ‘\0'; strcpy(rdParams.szUserName,szUser); strcpy(rdParams.szPassword,szPassword); rdParams.szDomain[0] = ‘\0'; // 以 下 開 始 同 步 撥 叫 網(wǎng) 絡(luò) dwRet = RasDial( NULL, NULL, &rdParams, 0L, NULL, &hCon ); return TRUE; } // 通 過FTP 協(xié) 議 讀 寫FTP 服 務(wù) 器 上 文 件 的 函 數(shù) cFlag =0 寫 =1 讀, 讀 寫 成 功 時(shí) 返 回 所 讀 寫 的 字 節(jié) 數(shù) DWORD FtpWriteRead(char * cFtpHost,char * cFile,DWORD dwLen,char * buf,char cFlag) { HINTERNET hInternet,hHost,hFile; DWORD dwLength,dwError; hInternet=InternetOpen(“FZYXB",LOCAL _INTERNET_ACCESS, NULL,0,0); hHost=InternetConnect(hInternet,cFtpHost, INTERNET_INVALID_PORT_NUMBER, “fzxucm",“abc505", INTERNET_SERVICE_FTP,INTERNET _FLAG_PASSIVE,0); if ( cFlag == 0 ) // 寫 hFile=FtpOpenFile(hHost,cFile,GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY,0); else hFile=FtpOpenFile(hHost,cFile,GENERIC_READ, FTP_TRANSFER_TYPE_BINARY,0); if( !hFile) { if ( (dwError=GetLastError()) == 12003 ) ShowMsg(hWin,“ 文 件 不 存 在"); InternetCloseHandle(hHost); InternetCloseHandle(hInternet);return 0L; } if ( cFlag == 0 ) InternetWriteFile(hFile,buf,dwLen, &dwLength); else InternetReadFile(hFile,buf,dwLen, &dwLength); InternetCloseHandle(hFile);InternetCloseHandle(hHost); InternetCloseHandle(hInternet); return dwLength; } // 通 過FTP 協(xié) 議 刪 除FTP 服 務(wù) 器 上 文 件 的 函 數(shù)cFtpHost 主 機(jī) 地 址cFile 文 件 名 BOOL MyFtpDeleteFile(char * cFtpHost,char * cFile) { HINTERNET hInternet,hHost; hInternet=InternetOpen(“FZYXB", LOCAL_INTERNET_ACCESS, NULL,0,0); hHost=InternetConnect(hInternet,cFtpHost, INTERNET_INVALID_PORT_NUMBER,“fzabc", “b505",INTERNET_SERVICE_FTP,INTERNET _FLAG_PASSIVE,0); FtpDeleteFile(hHost,cFile); InternetCloseHandle(hHost);InternetCloseHandle(hInternet); return TRUE; } // 本 地 計(jì) 算 機(jī) 運(yùn) 行 線 程 函 數(shù) pp 功 能 代 碼 void CallThread(void * pp ) { DWORD * dwId,dwLen, ret,ll; RASPPPIP rip; char szIp[50], *pdest; dwId=(DWORD *)pp; switch( * dwId ) { case IDC_CALL: // 通 知 遠(yuǎn) 程 計(jì) 算 機(jī) 登 錄Internet ShowMsg(hWin,“Call remote... "); if ( StartCon( hWin,“connect",“", “d123",“9W7607714" ) == TRUE ) { ShowMsg(hWin,“Remote Connected"); // 取remote 分 配 的IP 地 址 rip.dwSize=sizeof(RASPPPIP); if ( (ret=RasGetProjectionInfo(hCon,RASP_PppIp, (LPVOID) &rip,(LPDWORD) &ll ) ) != 0 ) ShowMsg(hWin,“ 取IP 地 址 失 敗"); else { ShowMsg(hWin,rip.szIpAddress); strcpy(szIp,rip.szIpAddress); pdest=strrchr(szIp,‘.'); *pdest=‘\0';strcat(szIp,“.1"); ShowMsg(hWin,szIp); SendCmd(szIp,“REQUEST"); } RasHangUp(hCon); } else ShowMsg(hWin,“Call remote fail"); hCon=NULL; break; case IDC_INTERNET: // 本 地 計(jì) 算 機(jī) 登 錄Internet ShowMsg(hWin,“ 正 在 連 接 Internet... "); StartCon( hWin,“internet",“l(fā)ocal@pub2.fz.fj.cn", “aabb99",“9W163" ); break; case IDC_ADDRESS: // 讀 取 遠(yuǎn) 程 計(jì) 算 機(jī)Internet IP 地 址 ShowMsg(hWin,“ 正 在 取 IP 地 址..."); if ( (dwLen=FtpWriteRead(“ftp.maoming.gd.cn", “abc.txt",40,cRemoteIP,1))>0 ) { cRemoteIP[dwLen]=‘\0';ShowMsg(hWin,cRemoteIP); ShowMsg(hWin,“ 刪 除IP 地 址 文 件.."); MyFtpDeleteFile(“ftp.maoming.gd.cn",“abc.txt"); } else ShowMsg(hWin,“ 取IP 失 敗"); break; case IDC_RDISC: // 通 知 遠(yuǎn) 程 計(jì) 算 機(jī) 斷 開Internet 連 接 ShowMsg(hWin,“ 正 在 向 遠(yuǎn) 端 發(fā) Disconnect..."); SendCmd(cRemoteIP,“DISCONNECT"); break; } ThreadId=0;hThread=NULL; return; } // 遠(yuǎn) 程 計(jì) 算 機(jī) 運(yùn) 行 線 程 函 數(shù) void ServerThread(void * pp ) { RASPPPIP rip; DWORD ret,ll; SOCKADDR_IN acc_sin, dest_sin; // 地 址 int acc_sin_len,status; char szMsg[ MY_MSG_LENGTH ]; serv_sock = socket(AF_INET,SOCK_STREAM,0); dest_sin.sin_family=AF_INET; dest_sin.sin_addr.s_addr=INADDR_ANY; dest_sin.sin_port=htons(1023); bind(serv_sock,(struct sockaddr FAR *) &dest_sin,sizeof(dest_sin)); listen(serv_sock,MAX_PENDING_CONNECTS); while( TRUE ) { acc_sin_len = sizeof(acc_sin);ShowMsg (hWin,“ 等 待 呼 叫"); rsock = accept( serv_sock,(struct sockaddr FAR *) &acc_sin,(int FAR *) &acc_sin_len ); if (rsock < 0) {ShowMsg(hWin,“Accept Error!");break;} ShowMsg(hWin,“ 收 到 連 接 請(qǐng) 求!"); status = recv( rsock, szMsg, MY_MSG_LENGTH, NO_FLAGS_SET ); if (status == SOCKET_ERROR) {ShowMsg(hWin,“Recv Error!");break;} if (status) { szMsg[status] = ‘\0'; ShowMsg(hWin,szMsg); if ( strstr(szMsg,“REQUEST") != NULL ) { isend(rsock,“OK",2,0); closesocket(rsock);Sleep(3000); // 等 待 撥 號(hào) 連 接 退 出 if (StartCon( hWin,“163",“remote@pub2.fz.fj.cn", “abcd",“163" ) == TRUE ) { // 取 動(dòng) 態(tài) 分 配 的IP 地 址 rip.dwSize=sizeof(RASPPPIP); if ( (ret=RasGetProjectionInfo(hCon,RASP_PppIp, (LPVOID) &rip,(LPDWORD) &ll ) ) != 0 ) {ShowMsg(hWin,“ 取IP 地 址 失 敗");break;} ShowMsg(hWin,rip.szIpAddress);ShowMsg(hWin, “ Send IP Adrress.... !"); FtpWriteRead( “ftp.maoming.gd.cn",“abc.txt", strlen(rip.szIpAddress),rip.szIpAddress,0); } else {ShowMsg(hWin,“Connect internet fail");} }//if ( strstr(szMsg,“REQUEST") != NULL ) if ( strstr(szMsg,“DISCONNECT") != NULL ) { send(rsock,“OK",2,0); closesocket(rsock);RasHangUp(hCon); } //end if ( strstr(szMsg,“DISCONNECT") != NULL ) } //end if (status) else {ShowMsg(hWin,“ 連 接 斷 開! 等 待 下 一 個(gè)"); closesocket(rsock);} } //end while( TRUE ) if(hCon != NULL ) {RasHangUp(hCon);Sleep(3000);} hCon =NULL;closesocket(serv_sock);hThread=NULL; return; } // 實(shí) 現(xiàn) 本 地 計(jì) 算 機(jī) 向 遠(yuǎn) 程 計(jì) 算 機(jī) 發(fā) 送 命 令 的 函 數(shù) cIp 遠(yuǎn) 程 計(jì) 算 機(jī) IP 地 址 SzCmd 命 令 字 符 串 BOOL SendCmd(char * cIp,char * szCmd) { SOCKADDR_IN dest_sin; // 地 址 int status; char szMsg[ MY_MSG_LENGTH ]; rsock = socket(AF_INET,SOCK_STREAM,0); dest_sin.sin_family=AF_INET;dest_sin.sin_ addr.s_addr = inet_addr(cIp); dest_sin.sin_port=htons(1023); if (connect( rsock,(PSOCKADDR) &dest_sin,sizeof(dest_sin) )<0 ) {ShowMsg(hWin,“ 連 接 失 敗"); closesocket( rsock );return FALSE;} if ( send(rsock,szCmd,strlen(szCmd),0) != strlen(szCmd)) {ShowMsg(hWin,“ 送 命 令 失 敗"); closesocket( rsock );return FALSE;} status = recv( rsock, szMsg, MY_MSG _LENGTH, NO_FLAGS_SET ); if (status == SOCKET_ERROR) {ShowMsg(hWin,“Recv Error!"); closesocket( rsock );return FALSE;} szMsg[status] = ‘\0'; if ( status != 0 & & strstr(szMsg,“OK") != NULL ) {closesocket( rsock );return TRUE;} closesocket( rsock );return FALSE; }
|