網絡編程小貼士
( 作者:mikespook | 發佈日期:2003-7-4 | 瀏覽次數:321 )
關鍵字:網絡,IP,主機名 |
本文已投稿《黑客安全基地》。文章爲《黑客安全基地》所有,未經《黑客安全基地》同意不得轉載。謝謝合作! 下面給大家介紹幾個常用的網絡編程小貼士。爲了方便起見,我將用C++ Builder 5來做演示程序。大家首先應該在C++ Builder 5中做一下配製。 對於小貼士一至四,你應該在Project Options中的Directories/Conditionals選項卡里添加“$(BCB)/lib/PSDK”到Library path中(圖1)。 並且在頭文件(<窗體>.h)中添加“#inclucde “wininet.h””。在<項目>.cpp文件中加入“USELIB(“wininet.lib”);”。 對於小貼士五、六,只要在頭文件(<窗體>.h)加入“#include “winsock2.h””即可。 在下面的例子中sbMsg是TstatusBar的實例。EdtURL、edtHostName是Tedit的實例。btnTip1、btnTip2、btnTip3、btnTip4、btnTip5、btnTip6是Tbutton的實例。 一、 嘗試進行網絡連接 要用的函數:InternetAttemptConnect 函數原形:DWORD InternetAttemptConnect(DWORD dwREserved); 這個函數可以說非常簡單,只是嘗試計算機連接到網絡。並不考慮是用什麼方式連接。當成功連接到網絡的時候,函數返回ERROR_SUCCESS,也就是0。函數的參數永遠都是0。有一點需要注意的是,當計算機是用“小貓”也就是撥號的方式上網的時候,在執行InternetAttemptConnect這個函數時,會自動激活撥號連接功能。這也就是很多軟件使用的撥號連接功能。比如Foxmail和FlashGet。 程序如下: void __fastcall TfrmMain::btnTip1Click(TObject *Sender) { if(ERROR_SUCCESS==InternetAttemptConnect(0)) sbMsg->SimpleText = "網絡連接成功!"; else sbMsg->SimpleText = "網絡連接失敗!"; } 二、 檢查遠程主機狀態 要用的函數:InternetCheckConnection 函數原形:BOOL InternetCheckConnection(LPCSTR lpszUrl, DWORD dwFlags, DWORD dwReserved); 這個函數的作用和PING命令是一樣的,可以檢查遠程主機是否連接。如果連接成功返回TRUE,如果連接失敗返回FALSE。參數lpszUrl是遠程主機的IP地址或URL。DwFlags只可設置一個值FLAG_ICC_FORCE_CONNECTION,也就是0x00000001。DwReserved是保留參數,只能設置爲0。 程序如下: void __fastcall TfrmMain::btnTip2Click(TObject *Sender) { if(InternetCheckConnection(edtURL->Text.c_str(), FLAG_ICC_FORCE_CONNECTION, 0)) sbMsg->SimpleText = "網絡連接成功!"; else sbMsg->SimpleText = "網絡連接失敗!"; } 三、 檢查本地網絡連接狀態並取得網絡連接方式 要用的函數:InternetGetConnectedState 函數原形:BOOL InternetGetConnectedState(LPDWORD lpdwFlags,DWORD dwReserved); 這個函數的功能是很強的。它可以: 1. 判斷網絡連接是通過網卡還是通過調治解調器 2. 是否通過代理上網 3. 判斷連接是On Line還是Off Line 4. 判斷是否安裝“撥號網絡服務” 5. 判斷調治解調器是否正在使用 這裏我們只需要使用它的第一條功能。參數lpdwFlags返回當前網絡狀態。這裏我們只要用下面兩個標誌進行判斷。 INTERNET_CONNECTION_MODEM 通過調治解調器連接網絡 INTERNET_CONNECTION_LAN 通過局域網連接網絡 參數dwReserved依然是保留參數,設置爲0即可。 當函數返回TRUE時說明連接到網絡,否則返回FALSE。 程序如下: void __fastcall TfrmMain::btnTip3Click(TObject *Sender) { DWORD dwFlag; if(!InternetGetConnectedState(&dwFlag, 0)) sbMsg->SimpleText = "網絡未連接。"; else if(dwFlag & INTERNET_CONNECTION_MODEM) sbMsg->SimpleText = "採用調治解調器上網。"; else if(dwFlag & INTERNET_CONNECTION_LAN) sbMsg->SimpleText = "採用網卡上網。"; } 四、 判斷是否使用代理連接 依然使用上面的這個InternetGetConnectedState函數。當lpdwFlags的標誌判斷爲INTERNET_CONNECTION_PROXY的時候,說明本地使用代理連接到網絡。 程序如下: void __fastcall TfrmMain::btnTip4Click(TObject *Sender) { DWORD dwFlag; if(!InternetGetConnectedState(&dwFlag, 0)) sbMsg->SimpleText = "網絡未連接。"; else if(dwFlag & INTERNET_CONNECTION_PROXY) sbMsg->SimpleText = "使用代理連接。"; else sbMsg->SimpleText = "未使用代理連接。"; } 五、 取得本機IP地址 要用的函數:gethostname、gethostbyname、inet_ntoa 函數原形: int gethostname(char FAR *name,int namelen); struct hostent FAR *gethostbyname(const char FAR *name); char FAR * inet_ntoa(struct in_addr in); 函數gethostname可以取得本地計算機主機名。參數name就是調用函數後保存主機名的字符指針。參數namelen是name參數的長度。 函數gethostbyname可以利用參數name傳入的主機名返回一個hostent結構。這個結構的原形如下: struct hostent { char FAR * h_name; char FAR * FAR * h_aliases; short h_addrtype; short h_length; char FAR * FAR * h_addr_list; }; 其中h_name返回主機名;h_aliases返回主機別名;h_addrtype返回IP地址的類型;h_length返回IP地址長度;h_addr_list返回IP地址。這裏特別要說明一下的是h_addr_list。因爲一臺計算機可能有多個有效的IP地址,所以h_addr_list實際上是一個數組。並且h_addr_list返回的是以網絡位順序表示的IP地址,還需要通過inet_ntoa函數轉化爲以“.”做分隔的IP地址。 函數inet_ntoa轉化網絡位順序表示的IP地址到“xxx.xxx.xxx.xxx”這種形式的IP地址。參數in是一個in_addr結構。我們只要知道怎麼使用inet_ntoa函數即可,如果想了解更多的內容可以去查MSDN。 程序如下: void __fastcall TfrmMain::btnTip5Click(TObject *Sender) { char cHostName[256]; AnsiString strAdd; gethostname(cHostName, sizeof(cHostName)); hostent *Host = gethostbyname(cHostName); if(NULL==Host) sbMsg->SimpleText = "獲取IP地址錯誤。"; else { in_addr addr; for(int i = 0; Host->h_addr_list[i] != 0; ++i) //注意這裏的循環 { memcpy(&addr, Host->h_addr_list[i], sizeof(in_addr)); strAdd = strAdd + " " + StrPas(inet_ntoa(addr)); } sbMsg->SimpleText = "本機IP地址爲"+strAdd; } } 這裏要特別說明一下的就是那個循環。前面說過了,因爲一臺計算機可能有多個有效的IP地址,所以h_addr_list實際上是一個數組。所以我們要利用這麼一個循環取得本地主機所有可能的IP。 六、 遠程主機名到IP地址的轉化 有了前面的講解,要進行遠程主機名到IP地址的轉化可以說是易如反掌。只要對程序進行下面的修改即可。 程序如下: void __fastcall TfrmMain::btnTip6Click(TObject *Sender) { char cHostName[256]; AnsiString strAdd; /* 注意這裏和小貼士五中的區別 gethostname(cHostName, sizeof(cHostName)); hostent *Host = gethostbyname(cHostName); */ hostent *Host = gethostbyname(edtHostName->Text.c_str()); if(NULL==Host) sbMsg->SimpleText = "獲取IP地址錯誤。"; else { in_addr addr; for(int i = 0; Host->h_addr_list[i] != 0; ++i) { memcpy(&addr, Host->h_addr_list[i], sizeof(in_addr)); strAdd = strAdd + " " + StrPas(inet_ntoa(addr)); } sbMsg->SimpleText ="計算機" + edtHostName->Text + "的IP地址爲"+strAdd; } } 這裏補充說明以下,當cHostName爲NULL的時候,函數取得的依然是本地主機的IP地址。 這六個小貼士是網絡編程中最常用的,也是最好用的小技巧。用好,用精的話,你可以寫出許許多多好用的小工具出來。 |