Code Example:
- The following programs demonstrate the use of getaddrinfo(), gai_strerror(), freeaddrinfo(), and getnameinfo(). The programs are an echo server and client for UDP datagrams.
服务器端程序:
- 1 ###Server program
- 2
- 3 #include <sys/types.h>
- 4 #include <stdio.h>
- 5 #include <stdlib.h>
- 6 #include <unistd.h>
- 7 #include <string.h>
- 8 #include <sys/socket.h>
- 9 #include <netdb.h>
- 10
- 11 #define BUF_SIZE 500
- 12
- 13 int
- 14 main(int argc, char *argv[])
- 15 {
- 16 struct addrinfo hints;
- 17 struct addrinfo *result, *rp;
- 18 int sfd, s;
- 19 struct sockaddr_storage peer_addr;
- 20 socklen_t peer_addr_len;
- 21 ssize_t nread;
- 22 char buf[BUF_SIZE];
- 23
- 24 if (argc != 2) {
- 25 fprintf(stderr, "Usage: %s port\n", argv[0]);
- 26 exit(EXIT_FAILURE);
- 27 }
- 28
- 29 memset(&hints, 0, sizeof(struct addrinfo));
- 30 hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
- 31 hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
- 32 hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
- 33 hints.ai_protocol = 0; /* Any protocol */
- 34 hints.ai_canonname = NULL;
- 35 hints.ai_addr = NULL;
- 36 hints.ai_next = NULL;
- 37
- 38 s = getaddrinfo(NULL, argv[1], &hints, &result);
- 39 if (s != 0) {
- 40 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
- 41 exit(EXIT_FAILURE);
- 42 }
- 43
- 44 /* getaddrinfo() returns a list of address structures.
- 45 Try each address until we successfully bind(2).
- 46 If socket(2) (or bind(2)) fails, we (close the socket
- 47 and) try the next address. */
- 48
- 49 for (rp = result; rp != NULL; rp = rp->ai_next) {
- 50 sfd = socket(rp->ai_family, rp->ai_socktype,
- 51 rp->ai_protocol);
- 52 if (sfd == -1)
- 53 continue;
- 54
- 55 if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
- 56 break; /* Success */
- 57
- 58 close(sfd);
- 59 }
- 60
- 61 if (rp == NULL) { /* No address succeeded */
- 62 fprintf(stderr, "Could not bind\n");
- 63 exit(EXIT_FAILURE);
- 64 }
- 65
- 66 freeaddrinfo(result); /* No longer needed */
- 67
- 68 /* Read datagrams and echo them back to sender */
- 69
- 70 for (;;) {
- 71 peer_addr_len = sizeof(struct sockaddr_storage);
- 72 nread = recvfrom(sfd, buf, BUF_SIZE, 0,
- 73 (struct sockaddr *) &peer_addr, &peer_addr_len);
- 74 if (nread == -1)
- 75 continue; /* Ignore failed request */
- 76
- 77 char host[NI_MAXHOST], service[NI_MAXSERV];
- 78
- 79 s = getnameinfo((struct sockaddr *) &peer_addr,
- 80 peer_addr_len, host, NI_MAXHOST,
- 81 service, NI_MAXSERV, NI_NUMERICSERV);
- 82 if (s == 0)
- 83 printf("Received %zd bytes from %s:%s\n",
- 84 nread, host, service);
- 85 else
- 86 fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));
- 87
- 88 if (sendto(sfd, buf, nread, 0,
- 89 (struct sockaddr *) &peer_addr,
- 90 peer_addr_len) != nread)
- 91 fprintf(stderr, "Error sending response\n");
- 92 }
- 93 }
客户端程序:
- 1 ###Client program
- 2
- 3 #include <sys/types.h>
- 4 #include <sys/socket.h>
- 5 #include <netdb.h>
- 6 #include <stdio.h>
- 7 #include <stdlib.h>
- 8 #include <unistd.h>
- 9 #include <string.h>
- 10
- 11 #define BUF_SIZE 500
- 12
- 13 int
- 14 main(int argc, char *argv[])
- 15 {
- 16 struct addrinfo hints;
- 17 struct addrinfo *result, *rp;
- 18 int sfd, s, j;
- 19 size_t len;
- 20 ssize_t nread;
- 21 char buf[BUF_SIZE];
- 22
- 23 if (argc < 3) {
- 24 fprintf(stderr, "Usage: %s host port msg...\n", argv[0]);
- 25 exit(EXIT_FAILURE);
- 26 }
- 27
- 28 /* Obtain address(es) matching host/port */
- 29
- 30 memset(&hints, 0, sizeof(struct addrinfo));
- 31 hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
- 32 hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
- 33 hints.ai_flags = 0;
- 34 hints.ai_protocol = 0; /* Any protocol */
- 35
- 36 s = getaddrinfo(argv[1], argv[2], &hints, &result);
- 37 if (s != 0) {
- 38 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
- 39 exit(EXIT_FAILURE);
- 40 }
- 41
- 42 /* getaddrinfo() returns a list of address structures.
- 43 Try each address until we successfully connect(2).
- 44 If socket(2) (or connect(2)) fails, we (close the socket
- 45 and) try the next address. */
- 46
- 47 for (rp = result; rp != NULL; rp = rp->ai_next) {
- 48 sfd = socket(rp->ai_family, rp->ai_socktype,
- 49 rp->ai_protocol);
- 50 if (sfd == -1)
- 51 continue;
- 52
- 53 if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
- 54 break; /* Success */
- 55
- 56 close(sfd);
- 57 }
- 58
- 59 if (rp == NULL) { /* No address succeeded */
- 60 fprintf(stderr, "Could not connect\n");
- 61 exit(EXIT_FAILURE);
- 62 }
- 63
- 64 freeaddrinfo(result); /* No longer needed */
- 65
- 66 /* Send remaining command-line arguments as separate
- 67 datagrams, and read responses from server */
- 68
- 69 for (j = 3; j < argc; j++) {
- 70 len = strlen(argv[j]) + 1;
- 71 /* +1 for terminating null byte */
- 72
- 73 if (len + 1 > BUF_SIZE) {
- 74 fprintf(stderr,
- 75 "Ignoring long message in argument %d\n", j);
- 76 continue;
- 77 }
- 78
- 79 if (write(sfd, argv[j], len) != len) {
- 80 fprintf(stderr, "partial/failed write\n");
- 81 exit(EXIT_FAILURE);
- 82 }
- 83
- 84 nread = read(sfd, buf, BUF_SIZE);
- 85 if (nread == -1) {
- 86 perror("read");
- 87 exit(EXIT_FAILURE);
- 88 }
- 89
- 90 printf("Received %zd bytes: %s\n", nread, buf);
- 91 }
- 92
- 93 exit(EXIT_SUCCESS);
- 94 }
Come from url: http://man7.org/linux/man-pages/man3/getaddrinfo.3.html