码迷,mamicode.com
首页 > 其他好文 > 详细

获取IP,GetLocalIP

时间:2015-03-02 11:15:50      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:结构   指针   delphi   pascal   

function GetLocalIP(var LocalIp: string): Boolean;
var
    HostEnt: PHostEnt;
    Ip: string;
    addr: pchar;
    Buffer: array [0..63] of char;
    GInitData: TWSADATA;
begin
  Result := False;
  try
    WSAStartup(2, GInitData);
    GetHostName(Buffer, SizeOf(Buffer));
    HostEnt := GetHostByName(buffer);
    if HostEnt = nil then Exit;
    addr := HostEnt^.h_addr_list^;
    ip := Format('%d.%d.%d.%d', [byte(addr [0]),
          byte (addr [1]), byte (addr [2]), byte (addr [3])]);
    LocalIp := Ip;
    Result := True;
  finally
    WSACleanup;
  end;
end;


WSAStartup使用详解

    摘要:首先说明WinSock编程中加载套接字库的一些基本内容,然后详细讲解了WSAStartup函数、WSACleanup函数、WSAData结构体的使用。最后给出示例代码说明套接字库的加载和版本协商。
    关键字:WSAStartup  WSACleanup  WSAData  套接字库加载版本协商
    Windows将socket的实现放到动态库中,利用套接字编程的第一步是加载套接字库。系统加载套接字的函数是WSAStartup。在使用这个函数时要注意,如果应用程序要求的套接字库版本号高于系统支持的版本号,WSAStartup返回成功,并且加载系统支持的最高版本号。这就要求在加载套接字库后判断是否是应用程序需求的版本号。每一次成功的调用了WSAStartup,都应该有对应的WSAClearup调用,以便于WinsockDLL释放启动时分配的资源。WSAStartup和WSAClearup可以多次调用,为了记录程序的调用次数,WinSock使用一个内部计数器,初始值为0,调用一次WSAStartup加一,调用一次WSAClearup减一。当减到0时,WSAClearup进行清除操作,它取消进程中任何线程中正在进行的阻塞或异步调用,而且不发送通知或者向事件对象发送信号。WSAClearup也取消正在进行的重叠操作,并且不设置事件对象或调用完成函数。
由于Windows将socket的实现放到动态库中,在用Winsock的API编程时,需要加载动态库。如果是加载2.2版本的套接字库,要使用winsock2.h头文件。示例代码如下
    #include<winsock2.h>
    #pragma comment(lib,"ws2_32.lib")

   上面的代码是调用Winsock2.2版本。版本1.1是Winsock.h和wsock32.lib。


WSAStartup
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);

功能:初始化WinSockDLL。本函数调用成功后才可以调用其他Winsock函数。
参数:
WORD wVersionRequested 加载套接字库的版本号。高位字节为副版本号,低位字节为主版本号。一般可以用MAKEWORD宏来为这个参数赋值(MAKEWORD宏的使用见文
章最后的附录)。
LPWSADATA  lpWSAData 出参 指向一个WSADATA结构体。这个结构体中包含了系统加载套接字库的相关信息(WSADATA结构体具体见本文WSADATA部分)。
返回值:成功返回0,失败返回非零。常见的失败代码如下(注意这些失败代码不是通过WSAGetLastError获得的,因为本函数没有调用成功,根本无法分配资源。所以这些代码是直接返回的):
WSASYSNOTREADY10091 底层的网络子系统无法使用
WSAVERNOTSUPPORTED 请求的版本系统不支持
WSAEINPROGRESS 一个阻塞的Socket正在调用
WSAEPROCLIM 任务数量已经到达了Socket所能够支持的最大数量
WSAEFAULT 参数lpWSAData的指针时无效指针

说明:如果在参数wVersionRequested中指定的Socket版本高于DLL中支持的最低版本,函数将调用成功。在参数lpWSAData指向的WSADATA变量中的wVersion成员保存了将要使用的版本号。所以一般的程序都要检查使用的版本号是否为要求的版本号(关于版本协商的更多内容见参考文献【2】)。常用的版本号1.1和2.2


WSAData 结构体
struct  WSAData{
WORD wVersion; //winsockdll期望调用者使用的版本
WORD wHighVersion; //winsockdll支持的最高版本号
char szDescription[WSADESCRIPTION_LEN+1]; //描述字符串
char szSystemStatus[WSASYSSTATUS_LEN+1]; //系统配置信息
unsignedshort iMaxSockets; //winsoc1.1中单个进程能够创建最大socket数,2.0后
//的版本没有用
unsignedshort iMaxUdpDg; //2.0后的版本没有用
charFAR* lpVendorInfo;//2.0后的版本没有用
};


WSACleanup
int WSACleanup(void)
功能:释放套接字库。
返回值:成功返回0,失败返回SOCKET_ERROR(-1)。
加载套接字库的示例代码
//参数mainVersion是套接字库的主板号
//参数subVersion 是套接字库的副版号
bool InitSocketLib(BYTE mainVersion,BYTE subVersion)
{
    WORD requestedVersion=MAKEWORD(subVersion,mainVersion);
    WSADATA wsaData;
    int err=WSAStartup(requestedVersion,&wsaData);
    if(0!=err){ //加载套接字失败
    return false;
}
    //进行版本协商,是否加载到需要的套接字版本库
    if(LOBYTE(wsaData.wVersion)!=mainVersion||
    HIBYTE(wsaData.wVersion)!=subVersion){
    WSACleanup();
    return false;
}
return true;
}

附录:
MAKEWORD
WORD MAKEWORD(
    BYTEbLow, //low-orderbyteofshortvalue
    BYTEbHigh //high-orderbyteofshortvalue
);
注意MAKEWORD是带参数的宏,不是函数。bLow是低位字节,bHigh是高位字节。
宏最后得到的结果是一个WORD类型的数值。


参考文献:
【1】WinSock简介fengliuall.blog.163.com/blog/static/23705110820147124139320/

【2】WinSock编程中的版本协商 hi.baidu.com/hphouylesmbceod/item/f8fe8b3c2aefffbdc2cf29a1


gethostname()

#include <Winsock2.h>
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操作正在进行。
参见:gethostbyname(), WSAAsyncGetHostByName()


gethostbyname()
返回对应于给定主机名的包含主机名字和地址信息的hostent结构指针。结构的声明与gethostaddr()中一致。

struct hostent{
  char*h_name;
  char*h_aliases;
  shorth_addrtype;
  shorth_length;
  char**h_addr_list;
};


获取IP,GetLocalIP

标签:结构   指针   delphi   pascal   

原文地址:http://blog.csdn.net/liuganggao/article/details/44014649

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!