1.Winsock 库的装入和释放
winsock应用程序都要加载相应的 Winsock DLL。
Winsock 库的加载函数是:
- int WSAStartup(
- WORD wVersionRequested,//指定要加载的Winsock库文件的版本。高位字节指出副版本(修正)号,低位字节指明主版本号
- LPWSADATA lpWSAData //lpWSAData 指向WSADATA数据结构的指针,用来接收Windows Sockets实现的细节。
- )
2.封装自己的CInitSock类
该类实现了载入和释放Winsock库
- /********************************************************************
- created: 2011/01/17
- created: 17:1:2011 10:44
- filename: D:/ Visual Studio/MyProjects/GetAllIps2/initsock.h
- file path: D:/ Visual Studio/MyProjects/GetAllIps2
- file base: initsock
- file ext: headfile
- author: jxusthusiwen
- purpose: 1.The definition socket program header file
- 2. 初始化WSAStartup():加载winsock库
- 3.初始化 WS2_32.dll库
- *********************************************************************/
- #include <winsock2.h>
- #pragma comment(lib,"WS2_32")
- class CInitSock
- {
- public :CInitSock(BYTE minorVer = 2,BYTE majorVer = 2)
- {
- WSADATA wsaData ;
- WORD sockVersion = MAKEWORD(minorVer,majorVer);
- //如果加载 Windows Sockets 1.1版本,只需要传参数 minorVer=1,majorVer=1
- if(::WSAStartup(sockVersion,&wsaData) !=0 )//如果初始化失败,返回0
- {
- exit(0);
- }
- //also can be defined like this
- /*
- int err;
- wVersionRequested =MAKEWORD(2,2);
- err = WSAStartup(wVersionRequesed,&wsaData);
- if(err != 0)
- {
- return 0;
- }
- */
- }
- ~CInitSock()//调用析构函数回收 开辟单元
- {
- ::WSACleanup();
- }
- };
3.获取主机的信息
hostent是host entry的缩写,该结构记录主机的信息,包括主机名、别名、地址类型、地址长度和地址列表。之所以主机的
地址是一个列表的形式,原因是当一个主机有多个网络接口时,自然有多个地址。hostent的定义如下:
- struct hostent {
- char *h_name;
- char **h_aliases;
- int h_addrtype;
- int h_length;
- char **h_addr_list;
- };
- #define h_addr h_addr_list[0]
数据结构的详细资料
struct hostent:
h_name – 地址的正式名称。
h_aliases – 空字节-地址的预备名称的指针。
h_addrtype – 地址类型; 通常是AF_INET。
h_length – 地址的比特长度。
h_addr_list – 零字节-主机网络地址指针。网络字节顺序。
h_addr - h_addr_list ---中的第一地址。
我们就是使用属性 h_addr_list – 零字节-主机网络地址指针,获取IP地址
4.获得本地主机名称
gethostname 函数原型:
- #include <Winsock2.h>
- int PASCAL FAR gethostname(char FAR *name, int namelen);
返回值:
如果没有错误发生,gethostname()返回0。
其中:
name: 一个指向将要存放主机名的缓冲区指针。
namelen:缓冲区的长度。
5.返回对应于给定主机名的包含主机名字和地址信息:gethostbyname()
函数原型:
- #include <winsock2.h>
- struct hostent *gethostbyname(const char * hostname);
返回hostent结构体指针。
6.inet_ntoa( user_inaddr /*一个in_addr变量*/)
函数功能:将网络地址转换成“.”点隔的字符串格式。
经过查阅MSDN
知 MSDN上本函数的原型描述为:unsigned long inet_addr( __in const char *cp);
所需头文件:
- #include <WINSOCK2.h>
- #pragma comment(lib,"WS2_32.LIB")
7.获取IP地址
经过以上的知识准备 编写代码测试 :
测试环境:vc6.0 ,
新建 win32 console application 空工程,工程名:GetIps
添加 initsock.h 头文件,和main.cpp源文件
- #include "InitSock.h"
- #include <stdio.h>
- CInitSock initsock;
- void main()
- {
- char szHost[256];
- //获取本机的主机地址 用户当前登录进入的主机(host).
- //任何用户的当前本地主机的回调地址(loop back address)总是127.0.0.1。
- ::gethostname(szHost,256);
- //通过主机名得到 地址信息
- hostent *pHost = ::gethostbyname(szHost);
- in_addr addr;//定义in_addr 变量 给inet_ntoa()调用
- //打印地址IP 信息
- for (int i =0; ; i++)
- {
- char * p = pHost->h_addr_list[i];
- if(p== NULL)
- {
- break;
- }
- memcpy(&addr.S_un.S_addr,p,pHost->h_length);
- //原型:extern void *memcpy(void *dest, void *src, unsigned int count);
- //usage example : memcpy(d,s,strlen(s));
- char * szIp = ::inet_ntoa(addr);
- printf("本机的IP地址:%s /n",szIp);
- }
- }