c-socket-programming:getaddrinfo
تفاوتها
تفاوت دو نسخهٔ متفاوت از صفحه را مشاهده میکنید.
| نگارش بعد | نگارش قبل | ||
| c-socket-programming:getaddrinfo [2024/06/18 00:58] – ایجاد شد pejman | c-socket-programming:getaddrinfo [2024/06/28 13:31] (فعلی) – pejman | ||
|---|---|---|---|
| خط 3: | خط 3: | ||
| معمولا از تابع ()getaddrinfo برای پر کردن استراکچر های مورد نیاز توابع دیگر یا ترجمه آدرس های اینترنتی استفاده میشود. | معمولا از تابع ()getaddrinfo برای پر کردن استراکچر های مورد نیاز توابع دیگر یا ترجمه آدرس های اینترنتی استفاده میشود. | ||
| - | | + | < |
| - | #include < | + | #include < |
| - | #include < | + | #include < |
| - | + | #include < | |
| - | int getaddrinfo(const char *node, const char *service, | + | |
| - | const struct addrinfo *hints, | + | |
| - | struct addrinfo **res); | + | |
| - | + | ||
| - | void freeaddrinfo(struct addrinfo *res); | + | |
| - | + | ||
| - | const char *gai_strerror(int errcode); | + | |
| + | int getaddrinfo(const char *restrict node, | ||
| + | const char *restrict service, | ||
| + | const struct addrinfo *restrict hints, | ||
| + | struct addrinfo **restrict res); | ||
| + | |||
| + | void freeaddrinfo(struct addrinfo *res); | ||
| + | |||
| + | const char *gai_strerror(int errcode); | ||
| + | |||
| + | |||
| + | Feature Test Macro Requirements for glibc (see feature_test_macros(7)): | ||
| + | |||
| + | getaddrinfo(), | ||
| + | Since glibc 2.22: | ||
| + | _POSIX_C_SOURCE >= 200112L | ||
| + | glibc 2.21 and earlier: | ||
| + | _POSIX_C_SOURCE | ||
| + | </ | ||
| تابع ()getaddrinfo یک node به عنوان Internet Host یک service و یک struct addrinfo به نام hints وارد میکند و نتیجه را در یک linked-list از نوع struct addrinfo به نام res باز میگرداند. خروجی این تابع در [[bind]] و [[connect]] قابل استفاده است. | تابع ()getaddrinfo یک node به عنوان Internet Host یک service و یک struct addrinfo به نام hints وارد میکند و نتیجه را در یک linked-list از نوع struct addrinfo به نام res باز میگرداند. خروجی این تابع در [[bind]] و [[connect]] قابل استفاده است. | ||
| خط 22: | خط 33: | ||
| استراکچر addrinfo : | استراکچر addrinfo : | ||
| <code C> | <code C> | ||
| - | // man 3 getaddrinfo | ||
| struct addrinfo { | struct addrinfo { | ||
| int ai_flags; | int ai_flags; | ||
| خط 47: | خط 57: | ||
| <code C> | <code C> | ||
| - | // man 7 ip | ||
| struct sockaddr_in { | struct sockaddr_in { | ||
| short int sin_family; | short int sin_family; | ||
| خط 55: | خط 64: | ||
| }; | }; | ||
| - | // man 7 ipv6 | ||
| struct sockaddr_in6 { | struct sockaddr_in6 { | ||
| u_int16_t | u_int16_t | ||
| خط 68: | خط 76: | ||
| <code C> | <code C> | ||
| - | // man 7 ip | ||
| - | // man 3 inet | ||
| - | // (IPv4 only--see struct in6_addr for IPv6) | ||
| - | // Internet address (a structure for historical reasons) | ||
| typedef uint32_t in_addr_t; | typedef uint32_t in_addr_t; | ||
| struct in_addr { | struct in_addr { | ||
| خط 77: | خط 81: | ||
| }; | }; | ||
| | | ||
| - | // man 7 ipv6 | ||
| struct in6_addr { | struct in6_addr { | ||
| unsigned char | unsigned char | ||
| }; | }; | ||
| </ | </ | ||
| + | |||
| در مثال زیر برای ترجمه نام اینترنتی به IP با کمک DNS ، از تابع ()getaddrinfo استفاده شده است. | در مثال زیر برای ترجمه نام اینترنتی به IP با کمک DNS ، از تابع ()getaddrinfo استفاده شده است. | ||
| <code C> | <code C> | ||
| + | // getaddrinfo.c | ||
| + | // gcc -std=c99 -Wall -Wextra -Werror -pedantic -o getaddrinfo getaddrinfo.c | ||
| + | |||
| + | #define _POSIX_C_SOURCE 200112L | ||
| #include < | #include < | ||
| خط 94: | خط 102: | ||
| #include < | #include < | ||
| #include < | #include < | ||
| - | |||
| int main() | int main() | ||
| { | { | ||
| - | char *node = " | + | |
| - | int errcode; | + | |
| - | struct addrinfo hints, *res ,*p; | + | |
| - | memset(& | + | |
| - | hints.ai_family = AF_UNSPEC; | + | hints.ai_family = AF_UNSPEC; |
| - | hints.ai_socktype = SOCK_STREAM; | + | hints.ai_socktype = SOCK_STREAM; |
| - | hints.ai_protocol = 0; | + | hints.ai_protocol = 0; |
| - | errcode = getaddrinfo(node, | + | int errcode = getaddrinfo(node, |
| - | if (errcode != 0) { | + | if (errcode != 0) { |
| - | fprintf(stderr, | + | fprintf(stderr, |
| - | exit(EXIT_FAILURE); | + | exit(EXIT_FAILURE); |
| - | } | + | } |
| - | printf(" | + | |
| - | for (p = res; p != NULL; p = p-> | + | |
| - | char *ipver, ipstr[INET6_ADDRSTRLEN]; | + | char *ipver, ipstr[INET6_ADDRSTRLEN]; |
| - | void *addr; | + | void *addr; |
| - | if (p-> | + | if (p-> |
| - | ipver = " | + | ipver = " |
| - | struct sockaddr_in *ipv4 = (struct sockaddr_in *)(p-> | + | struct sockaddr_in *ipv4 = (struct sockaddr_in *)(p-> |
| - | addr = & | + | addr = & |
| - | } else if (p-> | + | } else if (p-> |
| - | ipver = " | + | ipver = " |
| - | struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)(p-> | + | struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)(p-> |
| - | addr = & | + | addr = & |
| - | } else { | + | } else { |
| - | printf(" | + | printf(" |
| - | } | + | } |
| - | inet_ntop(p-> | + | inet_ntop(p-> |
| - | printf(" | + | printf(" |
| - | } | + | } |
| - | printf(" | + | |
| - | freeaddrinfo(res); | + | |
| - | return 0; | + | |
| } | } | ||
| - | |||
| </ | </ | ||
| خط 152: | خط 156: | ||
| IPv6: 2a00: | IPv6: 2a00: | ||
| + | |||
| + | |||
| + | همانطور که در قسمت Feature Test Macro در manual نوشته شده برای اینکه تعریف توابع ()getaddrinfo و ()freeaddrinfo و ()gai_strerror و استراکچر های مورد نیاز، از طریق header در دسترس باشند (expose شوند) در gcc های ورژن بالاتر از 2.22 باید ماکرو زیر تعریف شود | ||
| + | |||
| + | #define _POSIX_C_SOURCE 200112L | ||
| + | |||
| + | برای بررسی کار کرد ماکرو فوق، می توان یک بار بدون ماکرو و یک بار با وجود ماکرو، از دستور زیر استفاده کنیم و در خروجی، تعریف struct addrinfo را جستجو کنیم. خواهیم دید که بدون ماکرو فوق این استراکچر تعریف نمیشود | ||
| + | |||
| + | gcc -std=c99 -E getaddrinfo.c | ||
c-socket-programming/getaddrinfo.1718659713.txt.gz · آخرین ویرایش: 2024/06/18 00:58 توسط pejman
