获取IP地址getsockname gethostname

getsockname和gethostname都能获取IP地址,但是还是有却别的:

  • getsockname:  是获取跟某一特定的socket相关的IP地址。
  • gethostname:  是获取本机的所有的IP地址。

 

先来看下他们的获取Ip地址的方式。

  1. getsockname方式:

 

sockaddr_in test;

int len = sizeof(test);

if ( 0 == getsockname( m_socket, ( struct sockaddr* )&test, &len ))

{

char *pIPAddr = inet_ntoa(test.sin_addr);

}

这里假设m_socket是一个有效的套接字。

上面代码中pIPAddr就是想要获取的IP地址。

 

  1. gethostname方式:

 

TCHAR host[255];

host[0]= 0;

gethostname (host, 255); 

struct hostent FAR * pp;

pp = gethostbyname (host);

int i = 0;

while ( pp->h_addr_list[i++] != NULL) 

struct in_addr in;

in.s_addr = *((DWORD*)(&pp->h_addr_list[i][0]));

char *pAddr = inet_ntoa(in);

cout<<pAddr<<endl;

}

上面代码中pAddr就是获取的IP地址。

 

  其实gethostname对应的这段代码的效果和你在命令窗口中执行ipconfig /all效果是一样的。

 

gethostname你只要初始化了winsock库就可以直接使用上述代码得到本机的IP了(在linux中不需要,直接用)。但是getsockname方式来获取对应的IP地址的时候,首先需要通过socket函数创建的有效的套接字,另外还要bind。才能执行成功。如果在socket和bind之间调用就会调用失败。虽然在bind之后可以执行成功,通常我们得到的结果是0.0.0.0,除非在bind的时候就指定特定的IP。好先给一段简单的代码。

 

 

SOCKET socket1;

WSADATA wsaData;

if(WSAStartup(MAKEWORD(2,2), &wsaData))

{

printf(“Winsock can not be init!”);

WSACleanup();

return 0;

}

printf(“server begin to create socket!/n”);

//struct sockaddr_in local;

//struct sockaddr_in from;

sockaddr_in local;

sockaddr_in from;

int fromlen = sizeof(from);

local.sin_addr.s_addr = /*inet_addr( “192.168.200.141” );//*/INADDR_ANY;

local.sin_family =  AF_INET;

local.sin_port = htons(9101);

socket1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

if ( INVALID_SOCKET == socket1 )

{

printf( “failed to create socket” );

WSACleanup();

return 1;

}

 

if ( SOCKET_ERROR == bind(socket1, (struct sockaddr *)&local, fromlen))

{

printf( “failed to bind port” );

DWORD dw = GetLastError();

WSACleanup();

return 1;

}

//////////////////////////////////////////////////////////////////////////

sockaddr_in test1;

int len1 = sizeof(test1);

if ( 0 == getsockname( socket1, ( struct sockaddr* )&test1, &len1 ))

{

char *pTem1 = inet_ntoa(test1.sin_addr);

}

执行上面代码就会发现pTem1的值是0.0.0.0 。 如果我们把上述代码中的加粗的那行代码中的INADDR_ANY换成前面的inet_addr( “192.168.200.141” ); 再一次执行代码就会发现pTem1的值是192.168.200.141。
也许有人会问你不是在bind的时候知道自己绑定的是那个ip吗(一个可能有多个网卡),何必多此一举的去在调用api来获取呢?我这里这样列出只是为了说明问题,而实际的应用你根本不知道你拿到的socket对应的IP是多少你就可以通过这种方式来获取了。
  
上面列出的是基于数据报的UDP的情形,其实基于流式套接字的TCP是同样的效果。
  
上面的结论都在windows xp上面vc6下面测试得出。
下面再缀一点获取本机IP地址的方法,为什么说是缀,因为不是很相关.
如果想获取本机所有网卡的信息,当然也包括IP的信息。可以通过GetAdaptersInfo这个windows API。区别于上述方法的是,这个函数只能在windows上面,前面两个在windows和linux上面都可以。
  
下面列出用该方法的实例代码:
未完待续…

 

 

版权所有,禁止转载. 如需转载,请先征得博主的同意,并且表明文章出处,否则按侵权处理.

    分享到:

留言

你的邮箱是保密的 必填的信息用*表示