2 Star 0 Fork 0

Zzizy / tcp_c

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
servise 25.88 KB
一键复制 编辑 原始数据 按行查看 历史
Zzizy 提交于 2018-09-05 15:03 . getaddrinfo...
GETADDRINFO(3) Linux Programmer's Manual GETADDRINFO(3)
NNAAMMEE
getaddrinfo, freeaddrinfo, gai_strerror - network address and service translation
SSYYNNOOPPSSIISS
##iinncclluuddee <<ssyyss//ttyyppeess..hh>>
##iinncclluuddee <<ssyyss//ssoocckkeett..hh>>
##iinncclluuddee <<nneettddbb..hh>>
iinntt ggeettaaddddrriinnffoo((ccoonnsstt cchhaarr **_n_o_d_e,, ccoonnsstt cchhaarr **_s_e_r_v_i_c_e,,
ccoonnsstt ssttrruucctt aaddddrriinnffoo **_h_i_n_t_s,,
ssttrruucctt aaddddrriinnffoo ****_r_e_s));;
vvooiidd ffrreeeeaaddddrriinnffoo((ssttrruucctt aaddddrriinnffoo **_r_e_s));;
ccoonnsstt cchhaarr **ggaaii__ssttrreerrrroorr((iinntt _e_r_r_c_o_d_e));;
Feature Test Macro Requirements for glibc (see ffeeaattuurree__tteesstt__mmaaccrrooss(7)):
ggeettaaddddrriinnffoo(), ffrreeeeaaddddrriinnffoo(), ggaaii__ssttrreerrrroorr():
_POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
DDEESSCCRRIIPPTTIIOONN
Given _n_o_d_e and _s_e_r_v_i_c_e, which identify an Internet host and a service, ggeettaaddddrriinnffoo() returns one or more _a_d_d_r_i_n_f_o struc‐
tures, each of which contains an Internet address that can be specified in a call to bbiinndd(2) or ccoonnnneecctt(2). The ggeettaadd‐‐
ddrriinnffoo() function combines the functionality provided by the ggeetthhoossttbbyynnaammee(3) and ggeettsseerrvvbbyynnaammee(3) functions into a single
interface, but unlike the latter functions, ggeettaaddddrriinnffoo() is reentrant and allows programs to eliminate IPv4-versus-IPv6
dependencies.
The _a_d_d_r_i_n_f_o structure used by ggeettaaddddrriinnffoo() contains the following fields:
struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
socklen_t ai_addrlen;
struct sockaddr *ai_addr;
char *ai_canonname;
struct addrinfo *ai_next;
};
The _h_i_n_t_s argument points to an _a_d_d_r_i_n_f_o structure that specifies criteria for selecting the socket address structures
returned in the list pointed to by _r_e_s. If _h_i_n_t_s is not NULL it points to an _a_d_d_r_i_n_f_o structure whose _a_i___f_a_m_i_l_y, _a_i___s_o_c_k_‐
_t_y_p_e, and _a_i___p_r_o_t_o_c_o_l specify criteria that limit the set of socket addresses returned by ggeettaaddddrriinnffoo(), as follows:
_a_i___f_a_m_i_l_y This field specifies the desired address family for the returned addresses. Valid values for this field
include AAFF__IINNEETT and AAFF__IINNEETT66. The value AAFF__UUNNSSPPEECC indicates that ggeettaaddddrriinnffoo() should return socket addresses
for any address family (either IPv4 or IPv6, for example) that can be used with _n_o_d_e and _s_e_r_v_i_c_e.
_a_i___s_o_c_k_t_y_p_e This field specifies the preferred socket type, for example SSOOCCKK__SSTTRREEAAMM or SSOOCCKK__DDGGRRAAMM. Specifying 0 in this
field indicates that socket addresses of any type can be returned by ggeettaaddddrriinnffoo().
_a_i___p_r_o_t_o_c_o_l This field specifies the protocol for the returned socket addresses. Specifying 0 in this field indicates
that socket addresses with any protocol can be returned by ggeettaaddddrriinnffoo().
_a_i___f_l_a_g_s This field specifies additional options, described below. Multiple flags are specified by bitwise OR-ing them
together.
All the other fields in the structure pointed to by _h_i_n_t_s must contain either 0 or a null pointer, as appropriate.
Specifying _h_i_n_t_s as NULL is equivalent to setting _a_i___s_o_c_k_t_y_p_e and _a_i___p_r_o_t_o_c_o_l to 0; _a_i___f_a_m_i_l_y to AAFF__UUNNSSPPEECC; and _a_i___f_l_a_g_s
to ((AAII__VV44MMAAPPPPEEDD || AAII__AADDDDRRCCOONNFFIIGG)). (POSIX specifies different defaults for _a_i___f_l_a_g_s; see NOTES.) _n_o_d_e specifies either a
numerical network address (for IPv4, numbers-and-dots notation as supported by iinneett__aattoonn(3); for IPv6, hexadecimal string
format as supported by iinneett__ppttoonn(3)), or a network hostname, whose network addresses are looked up and resolved. If
_h_i_n_t_s_._a_i___f_l_a_g_s contains the AAII__NNUUMMEERRIICCHHOOSSTT flag, then _n_o_d_e must be a numerical network address. The AAII__NNUUMMEERRIICCHHOOSSTT flag
suppresses any potentially lengthy network host address lookups.
If the AAII__PPAASSSSIIVVEE flag is specified in _h_i_n_t_s_._a_i___f_l_a_g_s, and _n_o_d_e is NULL, then the returned socket addresses will be suit‐
able for bbiinndd(2)ing a socket that will aacccceepptt(2) connections. The returned socket address will contain the "wildcard
address" (IINNAADDDDRR__AANNYY for IPv4 addresses, IINN66AADDDDRR__AANNYY__IINNIITT for IPv6 address). The wildcard address is used by applications
(typically servers) that intend to accept connections on any of the hosts's network addresses. If _n_o_d_e is not NULL, then
the AAII__PPAASSSSIIVVEE flag is ignored.
If the AAII__PPAASSSSIIVVEE flag is not set in _h_i_n_t_s_._a_i___f_l_a_g_s, then the returned socket addresses will be suitable for use with ccoonn‐‐
nneecctt(2), sseennddttoo(2), or sseennddmmssgg(2). If _n_o_d_e is NULL, then the network address will be set to the loopback interface
address (IINNAADDDDRR__LLOOOOPPBBAACCKK for IPv4 addresses, IINN66AADDDDRR__LLOOOOPPBBAACCKK__IINNIITT for IPv6 address); this is used by applications that
intend to communicate with peers running on the same host.
_s_e_r_v_i_c_e sets the port in each returned address structure. If this argument is a service name (see sseerrvviicceess(5)), it is
translated to the corresponding port number. This argument can also be specified as a decimal number, which is simply
converted to binary. If _s_e_r_v_i_c_e is NULL, then the port number of the returned socket addresses will be left uninitial‐
ized. If AAII__NNUUMMEERRIICCSSEERRVV is specified in _h_i_n_t_s_._a_i___f_l_a_g_s and _s_e_r_v_i_c_e is not NULL, then _s_e_r_v_i_c_e must point to a string con‐
taining a numeric port number. This flag is used to inhibit the invocation of a name resolution service in cases where it
is known not to be required.
Either _n_o_d_e or _s_e_r_v_i_c_e, but not both, may be NULL.
The ggeettaaddddrriinnffoo() function allocates and initializes a linked list of _a_d_d_r_i_n_f_o structures, one for each network address
that matches _n_o_d_e and _s_e_r_v_i_c_e, subject to any restrictions imposed by _h_i_n_t_s, and returns a pointer to the start of the
list in _r_e_s. The items in the linked list are linked by the _a_i___n_e_x_t field.
There are several reasons why the linked list may have more than one _a_d_d_r_i_n_f_o structure, including: the network host is
multihomed, accessible over multiple protocols (e.g., both AAFF__IINNEETT and AAFF__IINNEETT66); or the same service is available from
multiple socket types (one SSOOCCKK__SSTTRREEAAMM address and another SSOOCCKK__DDGGRRAAMM address, for example). Normally, the application
should try using the addresses in the order in which they are returned. The sorting function used within ggeettaaddddrriinnffoo() is
defined in RFC 3484; the order can be tweaked for a particular system by editing _/_e_t_c_/_g_a_i_._c_o_n_f (available since glibc
2.5).
If _h_i_n_t_s_._a_i___f_l_a_g_s includes the AAII__CCAANNOONNNNAAMMEE flag, then the _a_i___c_a_n_o_n_n_a_m_e field of the first of the _a_d_d_r_i_n_f_o structures in
the returned list is set to point to the official name of the host.
The remaining fields of each returned _a_d_d_r_i_n_f_o structure are initialized as follows:
* The _a_i___f_a_m_i_l_y, _a_i___s_o_c_k_t_y_p_e, and _a_i___p_r_o_t_o_c_o_l fields return the socket creation parameters (i.e., these fields have the
same meaning as the corresponding arguments of ssoocckkeett(2)). For example, _a_i___f_a_m_i_l_y might return AAFF__IINNEETT or AAFF__IINNEETT66;
_a_i___s_o_c_k_t_y_p_e might return SSOOCCKK__DDGGRRAAMM or SSOOCCKK__SSTTRREEAAMM; and _a_i___p_r_o_t_o_c_o_l returns the protocol for the socket.
* A pointer to the socket address is placed in the _a_i___a_d_d_r field, and the length of the socket address, in bytes, is
placed in the _a_i___a_d_d_r_l_e_n field.
If _h_i_n_t_s_._a_i___f_l_a_g_s includes the AAII__AADDDDRRCCOONNFFIIGG flag, then IPv4 addresses are returned in the list pointed to by _r_e_s only if
the local system has at least one IPv4 address configured, and IPv6 addresses are returned only if the local system has at
least one IPv6 address configured. The loopback address is not considered for this case as valid as a configured address.
This flag is useful on, for example, IPv4-only systems, to ensure that ggeettaaddddrriinnffoo() does not return IPv6 socket addresses
that would always fail in ccoonnnneecctt(2) or bbiinndd(2).
If _h_i_n_t_s_._a_i___f_l_a_g_s specifies the AAII__VV44MMAAPPPPEEDD flag, and _h_i_n_t_s_._a_i___f_a_m_i_l_y was specified as AAFF__IINNEETT66, and no matching IPv6
addresses could be found, then return IPv4-mapped IPv6 addresses in the list pointed to by _r_e_s. If both AAII__VV44MMAAPPPPEEDD and
AAII__AALLLL are specified in _h_i_n_t_s_._a_i___f_l_a_g_s, then return both IPv6 and IPv4-mapped IPv6 addresses in the list pointed to by
_r_e_s. AAII__AALLLL is ignored if AAII__VV44MMAAPPPPEEDD is not also specified.
The ffrreeeeaaddddrriinnffoo() function frees the memory that was allocated for the dynamically allocated linked list _r_e_s.
EExxtteennssiioonnss ttoo ggeettaaddddrriinnffoo(()) ffoorr IInntteerrnnaattiioonnaalliizzeedd DDoommaaiinn NNaammeess
Starting with glibc 2.3.4, ggeettaaddddrriinnffoo() has been extended to selectively allow the incoming and outgoing hostnames to be
transparently converted to and from the Internationalized Domain Name (IDN) format (see RFC 3490, _I_n_t_e_r_n_a_t_i_o_n_a_l_i_z_i_n_g
_D_o_m_a_i_n _N_a_m_e_s _i_n _A_p_p_l_i_c_a_t_i_o_n_s _(_I_D_N_A_)). Four new flags are defined:
AAII__IIDDNN If this flag is specified, then the node name given in _n_o_d_e is converted to IDN format if necessary. The source
encoding is that of the current locale.
If the input name contains non-ASCII characters, then the IDN encoding is used. Those parts of the node name
(delimited by dots) that contain non-ASCII characters are encoded using ASCII Compatible Encoding (ACE) before
being passed to the name resolution functions.
AAII__CCAANNOONNIIDDNN
After a successful name lookup, and if the AAII__CCAANNOONNNNAAMMEE flag was specified, ggeettaaddddrriinnffoo() will return the canonical
name of the node corresponding to the _a_d_d_r_i_n_f_o structure value passed back. The return value is an exact copy of
the value returned by the name resolution function.
If the name is encoded using ACE, then it will contain the _x_n_-_- prefix for one or more components of the name. To
convert these components into a readable form the AAII__CCAANNOONNIIDDNN flag can be passed in addition to AAII__CCAANNOONNNNAAMMEE. The
resulting string is encoded using the current locale's encoding.
AAII__IIDDNN__AALLLLOOWW__UUNNAASSSSIIGGNNEEDD, AAII__IIDDNN__UUSSEE__SSTTDD33__AASSCCIIII__RRUULLEESS
Setting these flags will enable the IDNA_ALLOW_UNASSIGNED (allow unassigned Unicode code points) and
IDNA_USE_STD3_ASCII_RULES (check output to make sure it is a STD3 conforming hostname) flags respectively to be
used in the IDNA handling.
RREETTUURRNN VVAALLUUEE
ggeettaaddddrriinnffoo() returns 0 if it succeeds, or one of the following nonzero error codes:
EEAAII__AADDDDRRFFAAMMIILLYY
The specified network host does not have any network addresses in the requested address family.
EEAAII__AAGGAAIINN
The name server returned a temporary failure indication. Try again later.
EEAAII__BBAADDFFLLAAGGSS
_h_i_n_t_s_._a_i___f_l_a_g_s contains invalid flags; or, _h_i_n_t_s_._a_i___f_l_a_g_s included AAII__CCAANNOONNNNAAMMEE and _n_a_m_e was NULL.
EEAAII__FFAAIILL
The name server returned a permanent failure indication.
EEAAII__FFAAMMIILLYY
The requested address family is not supported.
EEAAII__MMEEMMOORRYY
Out of memory.
EEAAII__NNOODDAATTAA
The specified network host exists, but does not have any network addresses defined.
EEAAII__NNOONNAAMMEE
The _n_o_d_e or _s_e_r_v_i_c_e is not known; or both _n_o_d_e and _s_e_r_v_i_c_e are NULL; or AAII__NNUUMMEERRIICCSSEERRVV was specified in
_h_i_n_t_s_._a_i___f_l_a_g_s and _s_e_r_v_i_c_e was not a numeric port-number string.
EEAAII__SSEERRVVIICCEE
The requested service is not available for the requested socket type. It may be available through another socket
type. For example, this error could occur if _s_e_r_v_i_c_e was "shell" (a service available only on stream sockets), and
either _h_i_n_t_s_._a_i___p_r_o_t_o_c_o_l was IIPPPPRROOTTOO__UUDDPP, or _h_i_n_t_s_._a_i___s_o_c_k_t_y_p_e was SSOOCCKK__DDGGRRAAMM; or the error could occur if _s_e_r_v_i_c_e
was not NULL, and _h_i_n_t_s_._a_i___s_o_c_k_t_y_p_e was SSOOCCKK__RRAAWW (a socket type that does not support the concept of services).
EEAAII__SSOOCCKKTTYYPPEE
The requested socket type is not supported. This could occur, for example, if _h_i_n_t_s_._a_i___s_o_c_k_t_y_p_e and _h_i_n_t_s_._a_i___p_r_o_‐
_t_o_c_o_l are inconsistent (e.g., SSOOCCKK__DDGGRRAAMM and IIPPPPRROOTTOO__TTCCPP, respectively).
EEAAII__SSYYSSTTEEMM
Other system error, check _e_r_r_n_o for details.
The ggaaii__ssttrreerrrroorr() function translates these error codes to a human readable string, suitable for error reporting.
FFIILLEESS
_/_e_t_c_/_g_a_i_._c_o_n_f
AATTTTRRIIBBUUTTEESS
For an explanation of the terms used in this section, see aattttrriibbuutteess(7).
┌────────────────┬───────────────┬────────────────────┐
│IInntteerrffaaccee │ AAttttrriibbuuttee │ VVaalluuee │
├────────────────┼───────────────┼────────────────────┤
│ggeettaaddddrriinnffoo() │ Thread safety │ MT-Safe env locale │
├────────────────┼───────────────┼────────────────────┤
│ffrreeeeaaddddrriinnffoo(), │ Thread safety │ MT-Safe │
│ggaaii__ssttrreerrrroorr() │ │ │
└────────────────┴───────────────┴────────────────────┘
CCOONNFFOORRMMIINNGG TTOO
POSIX.1-2001, POSIX.1-2008. The ggeettaaddddrriinnffoo() function is documented in RFC 2553.
NNOOTTEESS
ggeettaaddddrriinnffoo() supports the _a_d_d_r_e_s_s%%_s_c_o_p_e_-_i_d notation for specifying the IPv6 scope-ID.
AAII__AADDDDRRCCOONNFFIIGG, AAII__AALLLL, and AAII__VV44MMAAPPPPEEDD are available since glibc 2.3.3. AAII__NNUUMMEERRIICCSSEERRVV is available since glibc 2.3.4.
According to POSIX.1, specifying _h_i_n_t_s as NULL should cause _a_i___f_l_a_g_s to be assumed as 0. The GNU C library instead
assumes a value of ((AAII__VV44MMAAPPPPEEDD || AAII__AADDDDRRCCOONNFFIIGG)) for this case, since this value is considered an improvement on the spec‐
ification.
EEXXAAMMPPLLEE
The following programs demonstrate the use of ggeettaaddddrriinnffoo(), ggaaii__ssttrreerrrroorr(), ffrreeeeaaddddrriinnffoo(), and ggeettnnaammeeiinnffoo(3). The pro‐
grams are an echo server and client for UDP datagrams.
SSeerrvveerr pprrooggrraamm
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#define BUF_SIZE 500
int
main(int argc, char *argv[])
{
struct addrinfo hints;
struct addrinfo *result, *rp;
int sfd, s;
struct sockaddr_storage peer_addr;
socklen_t peer_addr_len;
ssize_t nread;
char buf[BUF_SIZE];
if (argc != 2) {
fprintf(stderr, "Usage: %s port\n", argv[0]);
exit(EXIT_FAILURE);
}
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
hints.ai_protocol = 0; /* Any protocol */
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
s = getaddrinfo(NULL, argv[1], &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
/* getaddrinfo() returns a list of address structures.
Try each address until we successfully bind(2).
If socket(2) (or bind(2)) fails, we (close the socket
and) try the next address. */
for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sfd == -1)
continue;
if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
break; /* Success */
close(sfd);
}
if (rp == NULL) { /* No address succeeded */
fprintf(stderr, "Could not bind\n");
exit(EXIT_FAILURE);
}
freeaddrinfo(result); /* No longer needed */
/* Read datagrams and echo them back to sender */
for (;;) {
peer_addr_len = sizeof(struct sockaddr_storage);
nread = recvfrom(sfd, buf, BUF_SIZE, 0,
(struct sockaddr *) &peer_addr, &peer_addr_len);
if (nread == -1)
continue; /* Ignore failed request */
char host[NI_MAXHOST], service[NI_MAXSERV];
s = getnameinfo((struct sockaddr *) &peer_addr,
peer_addr_len, host, NI_MAXHOST,
service, NI_MAXSERV, NI_NUMERICSERV);
if (s == 0)
printf("Received %zd bytes from %s:%s\n",
nread, host, service);
else
fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));
if (sendto(sfd, buf, nread, 0,
(struct sockaddr *) &peer_addr,
peer_addr_len) != nread)
fprintf(stderr, "Error sending response\n");
}
}
CClliieenntt pprrooggrraamm
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUF_SIZE 500
int
main(int argc, char *argv[])
{
struct addrinfo hints;
struct addrinfo *result, *rp;
int sfd, s, j;
size_t len;
ssize_t nread;
char buf[BUF_SIZE];
if (argc < 3) {
fprintf(stderr, "Usage: %s host port msg...\n", argv[0]);
exit(EXIT_FAILURE);
}
/* Obtain address(es) matching host/port */
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
hints.ai_flags = 0;
hints.ai_protocol = 0; /* Any protocol */
s = getaddrinfo(argv[1], argv[2], &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
/* getaddrinfo() returns a list of address structures.
Try each address until we successfully connect(2).
If socket(2) (or connect(2)) fails, we (close the socket
and) try the next address. */
for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sfd == -1)
continue;
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
break; /* Success */
close(sfd);
}
if (rp == NULL) { /* No address succeeded */
fprintf(stderr, "Could not connect\n");
exit(EXIT_FAILURE);
}
freeaddrinfo(result); /* No longer needed */
/* Send remaining command-line arguments as separate
datagrams, and read responses from server */
for (j = 3; j < argc; j++) {
len = strlen(argv[j]) + 1;
/* +1 for terminating null byte */
if (len + 1 > BUF_SIZE) {
fprintf(stderr,
"Ignoring long message in argument %d\n", j);
continue;
}
if (write(sfd, argv[j], len) != len) {
fprintf(stderr, "partial/failed write\n");
exit(EXIT_FAILURE);
}
nread = read(sfd, buf, BUF_SIZE);
if (nread == -1) {
perror("read");
exit(EXIT_FAILURE);
}
printf("Received %zd bytes: %s\n", nread, buf);
}
exit(EXIT_SUCCESS);
}
SSEEEE AALLSSOO
ggeettaaddddrriinnffoo__aa(3), ggeetthhoossttbbyynnaammee(3), ggeettnnaammeeiinnffoo(3), iinneett(3), ggaaii..ccoonnff(5), hhoossttnnaammee(7), iipp(7)
CCOOLLOOPPHHOONN
This page is part of release 4.04 of the Linux _m_a_n_-_p_a_g_e_s project. A description of the project, information about report‐
ing bugs, and the latest version of this page, can be found at http://www.kernel.org/doc/man-pages/.
GNU 2015-07-23 GETADDRINFO(3)
C
1
https://gitee.com/2izy/tcp_c.git
git@gitee.com:2izy/tcp_c.git
2izy
tcp_c
tcp_c
master

搜索帮助