您的位置:首页 > 理论基础 > 计算机网络

网络编程小贴士

2004-06-25 22:07 267 查看

网络编程小贴士

( 作者: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地址。

  这六个小贴士是网络编程中最常用的,也是最好用的小技巧。用好,用精的话,你可以写出许许多多好用的小工具出来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: