首页 - 图片 - 汽车 - 百科 - 旅游 - 美食 - 英语 - IT资讯 - 留学 - 移民 - 电影 - 下载 - 站点地图

您的位置: 易飞网 >> 资讯 >> 电脑网络 >> C语言学习资料 >> 查看资讯

Windows下C语言网络编程快速入门

  二、 获取本地计算机的主机名和IP地址

  和C语言一样,函数是Windows C编程的最基本的单位。不过,Windows C主要使用API函数,而网络编程则主要使用Winsock提供的API函数。

  Winsock是90年代初,为了方便网络编程,由Microsoft联合了其他几家公司共同制定的一套WINDOWS下的网络编程接口,它是通过C语言的动态链接库方式提供给用户及软件开发者的,主要由winsock.h头文件和动态链接库winsock.dll组成,目前有两个版本:Winsock1.1和Winsock2.0。

  在Win32平台上,访问众多的基层网络协议,Winsock是首选接口。

  用Visual C++6.0编译Windows C程序,使用Winsock API函数时,首先要把wsock32.lib添加到它的库模块中,否刚在链接的时候,会出现“error LNK2001”错误。添加wsock32.lib的具体步骤是:打开工程菜单,选择设置,在弹出的Project settings对话框中,点击link选项卡,然后在对象/库模块文本框中添加wsock32.lib。

  最简单的网络编程是获取本机的主机名和IP地址,这个程序使用了WSAStart()、WSAClenaup()、gethostname()、gethostbyname()四个winsock API函数,这四个函数的功能和使用方法介绍如下:

  1. WSAStartup():

  【函数原型】

int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData);

  【使用说明】

  每一个使用winsock的应用程序,都必须进行WSAStart函数调用,并且只有在调用成功之后才能使用其它的winsock网络操作函数。

  WVersionRequired:<输入>表示欲使用的Winsock版本,这是一个WORD类型的整数,它的高位字节定义的是次版本号,低位字节定义的是主版本号。

  LpWSAData:<输出>是一个指向WSADATA资料的指针。这个资料我们一般不使用。

  返回值:调用成功返回0;否则,返回出错信息。

  2. WSAClenaup():

  【函数原型】

int PASCAL FAR WSACleanup(void);

  【使用说明】

  winsock使用后,要调用WSACleanup函数关闭网络设备,以便释放其占用的资源。

  3.gethostname()

  【函数原型】

int PASCAL FAR gethostname (char FAR * name, int namelen);

  【使用说明】

  该函数可以获取本地主机的主机名,其中:

  name:<输出>用于指向所获取的主机名的缓冲区的指针。

  Namelen:<输入>缓冲区的大小,以字节为单位。

  返回值:若无错误,返回0;否则,返回错误代吗。

  4.gethostbyname()

  【函数原型】

struct hostent FAR * PASCAL FAR gethostbyname(const char FAR * name);

  【使用说明】

  该函数可以从主机名数据库中得到对应的“主机”。

  该函数唯一的参数name就是前面调用函数gethostname()得到的主机名。若无错误,刚返回一个指向hostent结构的批针,它可以标识一个“主机”列表。

  Hostent结构定义如下:

Struct hostent
{
char FAR * h_name;
char FAR FAR ** h_aliases;
short h_addrtype;
char FAR FAR ** h_addr_list;
}

  其中:

  h_name:<输入>主机名地址(PC)。
  h_aliases:一个由主机备用名组成的空中止数组。
  H_addrtype:返回地址的类型,对于Winsock,这个域总是PF_INET。
  H_lenth:每个地址的长度(字节数),对应于PF_INET域应该为4。
  H_addr_list:应该以空指针结尾的主机地址的列表,返回的地址是以网络顺序排列的。

  其中,h_addr_list存放的就是本地主机的4个字节的IP地址,即:

  h_addr_list.h_addr_list.h_addr_list.h_addr_list

  一个简单的用消息框显示主机名和IP地址的源程序如下:

#include<winsock.h>

int WSA_return;
WSADATA WSAData;

HOSTENT *host_entry;
char host_name;
char host_address;

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine,int nCmdShow)
{
 WSA_return=WSAStartup(0x0101,&WSAData);

 if(WSA_return==0)
 {
  gethostname(host_name,256);
  host_entry=gethostbyname(host_name);
  if(host_entry!=0)
  {
   wsprintf(host_address,"%d.%d.%d.%d",
    (host_entry->h_addr_list&0x00ff),
    (host_entry->h_addr_list&0x00ff),
    (host_entry->h_addr_list&0x00ff),
    (host_entry->h_addr_list&0x00ff));

   MessageBox(NULL,host_address,host_name,MB_OK);
  }
 }
 WSACleanup();
 return 0;
}

  深入编程:

  前面显示IP地址的时候,我们使用的是消息框,规范一点的编程应该使用对话框,如何编辑一个对话框,很多书中都有介绍,编辑的对话框可参考图5的运行界面。

  头文件Get_IP.h如下:

BOOL APIENTRY Hostname_ipDlgPro(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);


  这个程序只使用了一个对话框过程,一般把这个过程的声明放在头文件中。

  源程序Get_IP.c:

#include<winsock2.h>
#include"Get_IP.h"
#include"resource.h" //这个头文件在创建资源的时候会自动生成,
//并会在插入资源时自动生成控件标识号.
int WSA_return;
WSADATA WSAData;

HOSTENT *host_entry;
char host_name;
char host_address;

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine,int nCmdShow)
{
 WSA_return=WSAStartup(0x0101,&WSAData);
 if(WSA_return==0)
 {
  gethostname(host_name,256);
  host_entry=gethostbyname(host_name);
  if(host_entry!=0)
  {
   wsprintf(host_address,"%d.%d.%d.%d",
    (host_entry->h_addr_list&0x00ff),
    (host_entry->h_addr_list&0x00ff),
    (host_entry->h_addr_list&0x00ff),
    (host_entry->h_addr_list&0x00ff));
  }
 }
 WSACleanup();
 DialogBox(hInstance,"DIALOG1",NULL,(DLGPROC)Hostname_ipDlgPro);
 return 0;
}

BOOL APIENTRY Hostname_ipDlgPro(HWND hDlg,UINT message,
WPARAM wParam,LPARAM lParam)
{
 switch(message)
 {
  case WM_INITDIALOG:
   return(TRUE);
  case WM_COMMAND:
   if(LOWORD(wParam)==IDOK)
   {
    SetDlgItemText(hDlg,IDC_EDIT1,host_name);
    SetDlgItemText(hDlg,IDC_EDIT2,host_address);
    SetDlgItemText(hDlg,IDCANCEL,"确定");
   }
   if(LOWORD(wParam)==IDCANCEL)
    EndDialog(hDlg,TRUE);
    return(TRUE);
   break;
 }
 return(FALSE);
}

     

 

22/2<12