擷取IP地址getsockname gethostname

來源:互聯網
上載者:User

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上面都可以。  下面列出用該方法的執行個體代碼:未完待續...

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.