Getaddrinfo () function details
1. Overview
In IPv4, The gethostbyname () function is used to resolve the host name to the address. This function only supports IPv4 and does not allow the caller to specify any information of the desired address type, the returned structure only contains the space used to store IPv4 addresses. The new getaddrinfo () API is introduced in IPv6. It is protocol-independent and can be used either IPv4 or IPv6. The getaddrinfo function can process the name-to-address and service-to-port conversions. The returned result is an addrinfo structure (list) pointer instead of an address list. These addrinfo structures can then be directly used by the set of interface functions. In this case, the getaddrinfo function hides the Protocol correlation security inside the library function. The application only needs to process the set interface address structure filled in by the getaddrinfo function. This function is defined in the POSIX specification.
2. Function Description
Include header files
# Include <netdb. h>
Function prototype
Int getaddrinfo (const char * hostname, const char * service, const struct addrinfo * hints, struct addrinfo ** result );
Parameter description
Hostname: A host name or address string (IPv4 dot-decimal string or IPv6 hexadecimal string)
Service: the service name can be a decimal port number or a defined service name, such as ftp or HTTP.
Hints: it can be a null pointer or a pointer to an addrinfo struct. The caller fills in this structure with hints about the type of information to be returned. For example, if the specified service supports both TCP and UDP, the caller can set the ai_socktype member in the hints structure to sock_dgram so that the returned information is only applicable to the datagram interface.
Result: This function returns a pointer to the addrinfo struct list through the result pointer parameter.
Returned value: 0 -- success, not 0 -- Error
3. parameter settings
Before the getaddrinfo function, you must set the following six parameters: nodename, servname, ai_flags, ai_family, ai_socktype, and ai_protocol of hints.
Among the six parameters, nodename, sername, and hints. ai_flag have the greatest impact on the function, while ai_family only differs from V4 or V6 addresses. Ai_protocol is generally set to 0 without modification.
Getaddrinfo common parameter settings in actual use
In general, in Client/Server programming, the server calls BIND (if listen is required for connection-oriented), the client does not need to drop the BIND function, and directly connect (connection-oriented) after resolving the address) or directly send data (no connection ). Therefore, common scenarios include:
(1) Before the server calls getaddrinfo, ai_flags sets ai_passive for bind. The nodename of the host name is usually set to null and the wildcard Address [:] is returned.
(2) When the client calls getaddrinfo, ai_flags generally does not set ai_passive, but the host name nodename and service name servname (more like called Port) should not be empty.
(3) Of course, even if ai_passive is not set, the retrieved address is not bind. In many programs, ai_flags is directly set to 0, that is, no three flag spaces are set, in this case, BIND is correct as long as the hostname and servname settings are correct.
The above is only a simple use of client/server, but when actually using getaddrinfo and referring to the open source code outside China, there were some problems with using servname (that is, Port) if it is set to null (of course, nodename must not be null at this time; otherwise, an error is returned when getaddrinfo is called ).
Tests were conducted in the following cases:
(1) If nodename is a string-type IPv6 address, a temporary port will be allocated during bind;
(2) If nodename is the local name and servname is null, it is slightly different from the Operating System. This article only tests on WINXP and win2003.
A) WINXP System (SP2) returns the loopback address [: 1]
B) win2003 returns the list of all IPv6 addresses on the local machine. Generally, an IPv6 host may have more than one IPv6 address, such as fe80: 1 (local loopback address), fe80: *** link-local address, and 3ffe:. In this case, calling getaddrinfo will return all these addresses. The caller should pay attention to how to use these addresses. In addition, you must specify the interface address when binding the fe80: address, that is, use fe80: 20d: 60ff: fe78: 51c2% 4 or fe80 :: in address format like 1% 1, The fe80 address can be directly taken out through getaddrinfo as if it cannot be directly bind.
4. Usage Details
If this function returns successfully, the variable pointed to by the result parameter has been filled with a pointer, which points to the addrinfo Structure linked list linked by the ai_next member. Multiple addrinfo structures can be returned:
1. If there are multiple addresses associated with the hostname parameter, each address in the requested address cluster returns a corresponding structure.
2. if the service parameter specifies that the Service supports multiple sets of interface types, each set of interface types may return a corresponding structure, depending on the ai_socktype Member of the hints structure.
We must first assign a hints structure, clear it, fill in the required fields, then call getaddrinfo, and traverse a linked list to try each return address one by one.
Getaddrinfo solves the problem of converting the interface address structure of Host Name and service name.
If getaddrinfo has an error, a non-zero error value is returned.
# Include <netdb. h>
Const char * gai_strerror (INT error );
This function takes the non-0 error value returned by getaddrinfo as its unique parameter and returns a pointer to the corresponding error message string.
All buckets returned by getaddrinfo are dynamically obtained. These buckets must be returned to the system by calling freeaddrinfo.
# Include <netdb. h>
Void freeaddrinfo (struct addrinfo * Ai );
The AI parameter should point to the first addrinfo structure returned by getaddrinfo. All the structures in the connected table and any dynamic storage space they direct to are released.
5. Example
Code
# Include <stdio. h>
# Include <stdlib. h>
# Include <sys/socket. h>
# Include <netinet/in. h>
# Include <netdb. h>
# Include <string. h>
Int main (INT argc, char ** argv)
{
If (argc! = 2 ){
Fprintf (stderr, "Usage: % s Hostname/N ",
Argv [1]);
Exit (1 );
}
Struct addrinfo * answer, hint, * curr;
Char ipstr [16];
Bzero (& hint, sizeof (hint ));
Hint. ai_family = af_inet;
Hint. ai_socktype = sock_stream;
Int ret = getaddrinfo (argv [1], null, & hint, & answer );
If (Ret! = 0 ){
Fprintf (stderr, "getaddrinfo: & S/N ",
Gai_strerror (RET ));
Exit (1 );
}
For (curr = answer; curr! = NULL; curr = curr-> ai_next ){
Inet_ntop (af_inet,
& (Struct sockaddr_in *) (curr-> ai_addr)-> sin_addr ),
Ipstr, 16 );
Printf ("% s/n", ipstr );
}
Freeaddrinfo (answer );
Exit (0 );
}