Reference book: "Advanced Programming in UNIX Environment" (APUE, the book of the male god, the third edition is out, if you need it, you can send a private message to me)
Article Directory
Structure definition
The addrinfo structure is mainly used when analyzing hostname in network programming. It is defined as follows in the header file #include<netdb.h>:
struct addrinfo
{
int ai_flags; /* Input flags. */
int ai_family; /* Protocol family for socket. */
int ai_socktype; /* Socket type. */
int ai_protocol; /* Protocol for socket. */
socklen_t ai_addrlen; /* Length of socket address. */
struct sockaddr *ai_addr; /* Socket address for socket. */
char *ai_canonname; /* Canonical name for service location. */
struct addrinfo *ai_next; /* Pointer to next in list. */
};
It can be said to be a new face or an old face, so let me introduce it?
Then introduce it: Okay, in fact, its introduction is quite clear.
Similar to sin_addr and s_addr.
Parameter definition:
ai_flags
Used to specify how to deal with addresses and names, the available values are as follows:
Just change the prefix, right
ai_family
I don’t even change the prefix here
ai_socktype
Same as above
ai_protocol
IPPROTO_IP :IP协议
IPPROTO_IPV4 :IPv4
IPPROTO_IPV6 :IPv6
IPPROTO_TCP :TCP
IPPROTO_UDP :UDP
There are many things in this change.
ai_next
Since a domain name can correspond to multiple IP addresses, addrinfo also supports this scenario. Addrinfo stores other addresses in a linked list, which can be obtained by traversing its attribute ai_next.
related functions
getaddrinfo
After looking around, I couldn't find its source code, so I could only post the statement, and then add it when I found it.
int getaddrinfo(const char *restrict nodename, /* host 或者IP地址 */
const char *restrict servname, /* 十进制端口号 或者常用服务名称如"ftp"、"http"等 */
const struct addrinfo *restrict hints, /* 获取信息要求设置 */
struct addrinfo **restrict res); /* 获取信息结果 */
Parameter definition:
nodename:
host name ("lion-wu.blog.csdn.net") or a digitized address string (IPv4 dotted decimal string ("192.168.128.64") or IPv6 hexadecimal string).
If the AI_NUMERICHOST flag is set in ai_flags, then this parameter can only be a digitized address string, not a domain name. The function of this flag is to prevent domain name resolution.
The nodename and servname can be set to NULL, but only one of them can be NULL at the same time.
servname: The
service name can be a decimal port number ("8080") string, or a defined service name, such as "ftp", "http", etc. Please check the /etc/services file for details, and finally translate it into the corresponding The port number of the service. If this parameter is set to NULL, the port number in the returned socket address will not be set.
If the AI_NUMERICSERV flag is set in ai_flags and the parameter is not set to NULL, then the parameter must be a decimal port number string and cannot be set as a service name. This flag is used to prevent service name parsing.
hints:
This parameter points to the struct addrinfo structure set by the user. Only the four fields of ai_family, ai_socktype, ai_protocol and ai_flags can be set in this structure. The other fields must be set to 0 or NULL, usually used after applying for structure variables memset() initializes and then sets the specified four fields.
This parameter can be set to NULL, which is equivalent to ai_socktype = 0, ai_protocol = 0, ai_family = AF_UNSPEC, ai_flags = 0.
res:
This parameter obtains a struct addrinfo structure list that points to the storage result, and calls freeaddrinfo() after use to release the storage result space.
return value
If the getaddrinfo() function is executed successfully, the return value is 0. In other cases, the return value indicates the type of error. Use the function gai_strerror() to get readable error information, and the usage is the same as strerror().
chestnut
ret = getaddrinfo("lion-wu.blog.csdn.net", NULL, &hint, &res);
if (ret != 0)
{
printf("getaddrinfo error\n");
return -1;
}
freeaddrinfo
void freeaddrinfo(struct addrinfo *ai)
{
struct addrinfo *next;
#if defined(__BIONIC__)
if (ai == NULL) return;
#else
_DIAGASSERT(ai != NULL);
#endif
do {
next = ai->ai_next;
if (ai->ai_canonname)
free(ai->ai_canonname);
/* no need to free(ai->ai_addr) */
free(ai);
ai = next;
} while (ai);
}
Usage example
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int ret = -1;
struct addrinfo *res;
struct addrinfo hint;
struct addrinfo *curr;
char ipstr[16];
if (argc != 2) {
printf("parameter error\n");
return -1;
}
bzero(&hint, sizeof(hint));
hint.ai_family = AF_INET;
hint.ai_socktype = SOCK_STREAM;
ret = getaddrinfo(argv[1], NULL, &hint, &res);
if (ret != 0)
{
printf("getaddrinfo error\n");
return -1;
}
for (curr = res; 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(res);
return 0;
}
Pro test:
Can you guess why the first operation failed?
Today's technical presentation on the matter here, I want to introduce one of my new friends:
Well ze lo boom Clang
our school chiefs Software Engineering, Java, algorithms, redis field bloggers, which are paid off.
Then, by the way, you can also check out my other blog, lion-wu.blog.csdn.net
Just swipe it and it's over, are you sure you don't leave it?