英雄联盟蛮王出装:获取主机的IP信息

来源:百度文库 编辑:九乡新闻网 时间:2024/05/02 09:43:29

#include "Winsock2.h"

1.MAKEWORD 宏 的使用

平台:SDK  这个宏创建一个被指定变量连接而成的WORD变量。返回一个WORD变量。  (注:typedef unsigned short WORD;)  WORD MAKEWORD(  BYTE bLow, //指定新变量的低字节序;  BYTE bHigh //指定新变量的高字节序;  );  例如:  WORD wVersionRequested;  wVersionRequested = MAKEWORD( 2, 2 );  #define MAKEWORD(a,b) ((WORD) (((BYTE) (a)) | ((WORD) ((BYTE) (b))) << 8))  makeword是将两个byte型合并成一个word型,一个在高8位(b),一个在低8位(a)  makelparam、makelong和makewparam都是一样的,将两个word型合并成一个dword型。一个在高16位,一个在低16位  delphi:word((byte(a)) or (word(byte(b))) shl 8);  比如a=2;b=1  2的二进制是00000010 1的二进制为00000001 B是表示高8位,A表示低8位 合并起来就是  100000010  想要的是MAKEWORE(1,1),MAKEWORD(2,2),有什么区别,是不是前面得只能一次接收一次,不能马上发送,后面的能。  比如:  #include   #include   using namespace std;  int main()  {  WORD wVersionRequested;  wVersionRequested=MAKEWORD(2,2);  cout << wVersionRequested << endl;  return 0;  }  输出的结果是514,说明是将前面的2和后面的2组成一个新的WORD。即0000 0010 0000 0010  而这个结果正是:512 + 2 = 514.

2.WSAStarup,是Windows SocKNDs Asynchronous的启动命令、Windows下的网络编程接口软件 Winsock1 或 Winsock2 里面的一个命令。

简介

  WSAStarup,即WSA(Windows SocKNDs Asynchronous,Windows套接字异步)的启动命令。是Windows下的网络编程接口软件 Winsock1 或 Winsock2 里面的一个命令(Ps:Winsock 是由Unix下的BSD Socket发展而来,是一个与网络协议无关的编程接口)。

详细说明

  为了在应用程序当中调用任何一个Winsock API函数,首先第一件事情就是必须通过WSAStartup函数完成对Winsock服务的初始化,因此需要调用WSAStartup函数。使用Socket的程序在使用Socket之前必须调用WSAStartup函数。该函数的第一个参数指明程序请求使用的Socket版本,其中高位字节指明副版本、低位字节指明主版本;操作系统利用第二个参数返回请求的Socket的版本信息。当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。

编辑本段函数原型

  #include  int PASCAL FAR WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData );wVersionRequested  Windows Sockets API提供的调用方可使用的最高版本号。高位字节指出副版本(修正)号,低位字节指明主版本号。lpWSAData 指向WSADATA数据结构的指针,用来接收Windows Sockets实现的细节。
3.返回本地主机的标准主机名。
//strHostIP 为 192.168.0.74  #include   int PASCAL FAR gethostname(char FAR *name, int namelen);  name: 一个指向将要存放主机名的缓冲区指针。  namelen:缓冲区的长度。  注释:  该函数把本地主机名存放入由name参数指定的缓冲区中。返回的主机名是一个以NULL结束的字符串。主机名的形式取决于Windows Sockets实现-它可能是一个简单的主机名,或者是一个域名。然而,返回的名字必定可以在gethostbyname()和WSAAsyncGetHostByName()中使用。  返回值:  如果没有错误发生,gethostname()返回0。否则它返回SOCKET_ERROR。应用程序可以通过WSAGetLastError()来得到一个特定的错误代码。  错误代码:  WSAEFAULT 名字长度参数太小。  WSANOTINTIALISED 在应用这个API前,必须成功地调用WSAStartup()。  WSAENTDOWN Windows Sockets实现检测到了网络子系统的错误。  WSAEINPROGRESS 一个阻塞的Windows Sockets操作正在进行。
4.gethostbyname()返回对应于给定主机名的包含主机名字和地址信息的hostent结构指针。结构的声明与gethostaddr()中一致。

简述

  返回对应于给定主机名的主机信息。  #include   struct hostent FAR *PASCAL FAR gethostbyname(const char  FAR * name);  name:指向主机名的指针。  Linux版  #include   struct hostent *gethostbyname(const char * hostname);  返回:非空指针——成功,空指针——出错,同时设置h_errno

编辑本段注释

  gethostbyname()返回对应于给定主机名的包含主机名字和地址信息的hostent结构指针。结构的声明与gethostaddr()中一致。  返回的指针指向一个由Windows Sockets实现分配的结构。应用程序不应该试图修改这个结构或者释放它的任何部分。此外,每一线程仅有一份这个结构的拷贝,所以应用程序应该在发出其他Windows Scokets API调用前,把自己所需的信息拷贝下来。  gethostbyname()实现没有必要识别传送给它的IP地址串。对于这样的请求,应该把IP地址串当作一个未知主机名同样处理。如果应用程序有IP地址串需要处理,它应该使用inet_addr()函数把地址串转换为IP地址,然后调用gethostbyaddr()来得到hostent结构。

编辑本段返回值

  如果没有错误发生,gethostbyname()返回如上所述的一个指向hostent结构的指针,否则,返回一个空指针。应用程序可以通过WSAGetLastError()来得到一个特定的错误代码。

5.  inet_ntoa函数功能:将网络地址转换成“.”点隔的字符串格式。  所需库: winsock.h  也可以使用:   头文件 Winsock2.h lib Ws2_32.lib dll Ws2_32.dll   即在程序开头写:  #include   #pragma comment(lib,"WS2_32.LIB")  函数原型: char FAR* PASCAL FAR inet_ntoa( struct in_addr in);  MSDN上本函数的原型描述为:unsigned long inet_addr( __in const char *cp);  in:一个表示Internet主机地址的结构。  注释:   本函数将一个用in参数所表示的Internet地址结构转换成以“.” 间隔的诸如“a.b.c.d”的字符串形式。请注意inet_ntoa()返回的字符串存放在WINDOWS套接口实现所分配的内存中。应用程序不应假设该内存是如何分配的。在同一个线程的下一个WINDOWS套接口调用前,数据将保证是有效。  返回值:   若无错误发生,inet_ntoa()返回一个字符指针。否则的话,返回NULL。其中的数据应在下一个WINDOWS套接口调用前复制出来。  相关函数:inet_addr().
6.hostent 是host entry的缩写,该结构记录主机的信息,包括主机名、别名、地址类型、地址长度和地址列表。之所以主机的地址是一个列表的形式,原因是当一个主机有多个网络接口时,自然有多个地址。hostent的定义如下:
struct hostent *gethostbyname(const char *name);
    这个函数的传入值是域名或者主机名,例如"www.google.cn"等等。传出值,是一个hostent的结构。如果函数调用失败,将返回NULL。

    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]
    };

    hostent->
h_name
    表示的是主机的规范名。例如www.google.com的规范名其实是www.l.google.com。
    hostent->h_aliases
    表示的是主机的别名.www.google.com就是google他自己的别名。有的时候,有的主机可能有好几个别名,这些,其实都是为了易于用户记忆而为自己的网站多取的名字。
    hostent->h_addrtype    
    表示的是主机ip地址的类型,到底是ipv4(AF_INET),还是pv6(AF_INET6)
    hostent->h_length      
    表示的是主机ip地址的长度
    hostent->h_addr_lisst
    表示的是主机的ip地址,注意,这个是以网络字节序存储的。千万不要直接用printf带%s参数来打这个东西,会有问题的哇。所以到真正需要打印出这个IP的话,需要调用inet_ntop()。

    const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) :
    这个函数,是将类型为af的网络地址结构src,转换成主机序的字符串形式,存放在长度为cnt的字符串中。返回指向dst的一个指针。如果函数调用错误,返回值是NULL。
  
HRESULT   GetHostInfo(CString& strHostIP){int nCheck = 0;WORD wVersion = 0;CString strName = _T("");CString strIP = _T("");in_addr *pIPAddr = NULL;HOSTENT *pstHostInfo = NULL;char chrName[256];WSADATA wsaData;
wVersion = MAKEWORD(2, 2);nCheck = WSAStartup(wVersion, &wsaData);nCheck |= gethostname(chrName, 256); if(nCheck != 0) { return E_FAIL; } strName = (CString)chrName; #ifdef _UNICODE USES_CONVERSION; pstHostInfo = gethostbyname(W2A(strName)); #else pstHostInfo = gethostbyname(strName.GetBuffer(strName.GetLength())); #endif if(pstHostInfo != NULL) { LPBYTE pBuffer = NULL; pBuffer = new BYTE[4]; memcpy(pBuffer, pstHostInfo->h_addr_list[0], 4); pIPAddr = (in_addr*)pBuffer; strIP = inet_ntoa(*pIPAddr); delete [] pBuffer; pBuffer = NULL; } else return E_FAIL; strHostIP = strIP; return S_OK;
}