获取IP,GetLocalIP

function GetLocalIP(var LocalIp: string): Boolean;varHostEnt: PHostEnt;Ip: string;addr: pchar;Buffer: array [0..63] of char;GInitData: TWSADATA;begin Result := False; tryWSAStartup(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; finallyWSACleanup; 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。

WSAStartupint 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后的版本没有用};WSACleanupint 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;}附录:MAKEWORDWORD MAKEWORD(BYTEbLow, //low-orderbyteofshortvalueBYTEbHigh //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操作正在进行。

没有一种不通过蔑视、忍受和奋斗就可以征服的命运。

获取IP,GetLocalIP

相关文章:

你感兴趣的文章:

标签云: