Both getsockname and gethostname can obtain IP addresses, but there are other IP addresses:
- Getsockname: gets the IP address related to a specific socket.
- Gethostname: obtains all IP addresses of the local machine.
Let's take a look at their way of getting IP addresses.
- Getsockname method:
Sockaddr_in test;
Int Len = sizeof (test );
If (0 = getsockname (m_socket, (struct sockaddr *) & test, & Len ))
{
Char * pipaddr = inet_ntoa (test. sin_addr );
}
Assume that m_socket is a valid socket.
In the above Code, pipaddr is the IP address to be obtained.
- Gethostname method:
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;
}
In the above Code, paddr is the obtained IP address.
In fact, the effect of the code corresponding to gethostname is the same as that of ipconfig/all in the Command window.
Gethostname you only need to initialize the Winsock library and you can directly use the above Code to obtain the IP address of the Local Machine (this is not required in Linux and can be used directly ). However, when getsockname is used to obtain the corresponding IP address, you must first use the socket function to create a valid socket and bind it. To be executed successfully. If the call is performed between the socket and bind, the call fails. Although it can be successfully executed after bind, the result is usually 0.0.0.0, unless a specific IP address is specified during bind. Let's give you a simple piece of code.
Socket socket1;
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 );
}
Run the above Code and you will find that the ptem1 value is 0.0.0.0. If we replace inaddr_any in the above Code with the previous
Inet_addr ("192.168.200.141 ");Once again, the ptem1 value is 192.168.200.141. Maybe someone will ask you if you know the IP address you bound when BIND (one may have multiple NICS). Why do you need to call the API to obtain the IP address? I listed it here only to illustrate the problem, but in actual application, you do not know the IP address of the socket you get, you can get it in this way. The above list is the UDP based on the datagram. In fact, the TCP based on the stream socket is the same effect. The above conclusions are all tested under vc6 on Windows XP. The following describes how to obtain the IP address of the Local Machine. Why is it because it is not relevant? If you want to obtain information about all the NICS of the Local Machine, of course, it also includes the IP address information. You can use the getadaptersinfo Windows API. Unlike the above method, this function can only be used on windows, and the first two functions can be used on both Windows and Linux. The instance code using this method is listed below: not complete To be continued...