#include #include #include #include #include #include #include #include #include int open_clientfd(char *hostname, char *port); #define MAXLINE 512 /* usage: ./echoclient host port */ int main(int argc, char *argv[]) { int clientfd; size_t n; char *host, *port, buf[MAXLINE]; host = argv[1]; port = argv[2]; clientfd = open_clientfd(host, port); if (clientfd < 0) { if (clientfd == -1) fprintf(stderr, "%s:%s: %s\n", host, port, strerror(errno)); exit(1); } while (fgets(buf, sizeof buf - 1, stdin) != NULL) { write(clientfd, buf, strlen(buf)); n = read(clientfd, buf, sizeof buf - 1); if (n != -1) { buf[n] = '\0'; fputs(buf, stdout); } } close(clientfd); exit(0); } int open_clientfd(char *hostname, char *port) { int clientfd; struct addrinfo hints; struct addrinfo *hostaddresses = NULL; struct addrinfo *addr; int error; /* Find out the server's IP address and port */ memset(&hints, 0, sizeof hints); hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED; hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(hostname, port, &hints, &hostaddresses); if (error != 0) { freeaddrinfo(hostaddresses); fprintf(stderr, "%s:%s: %s\n", hostname, port, gai_strerror(error)); return -1; } /* Walk the address list to find one that we can connect to */ for (addr = hostaddresses; addr != NULL; addr = addr->ai_next) { /* We take advantage of the fact that AF_* and PF_* are identical */ clientfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); if (clientfd == -1) continue; /* Socket failed, try next */ /* Establish a connection with the server */ if (connect(clientfd, addr->ai_addr, addr->ai_addrlen) != -1) break; /* Success! */ close(clientfd); /* Connect failed; try another */ } freeaddrinfo(hostaddresses); if (addr == NULL) return -1; /* All failed; check errno for cause */ return clientfd; }