#define _POSIX_SOURCE #include #include #include #include #include #include #include #define MAXSIZE 1024 /* * client.c: Implementation of a very simple tcp client. */ int main(int argc, char *argv[]) { struct addrinfo hints; /* specify our needs */ struct addrinfo *res; /* resulting address structure */ struct addrinfo *r; /* iterator */ int err; /* status of getaddrinfo() */ int s; /* socket */ char c1; /* compared to 'y' */ char c2; /* compared to '\n' */ char line[MAXSIZE]; /* message buffer */ /* Enforce correct usage */ if (argc != 3) { printf("Usage: %s [server] [port]\n", argv[0]); exit(EXIT_FAILURE); } memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; /* IPv4 */ hints.ai_socktype = SOCK_STREAM; /* Stream socket */ hints.ai_protocol = 0; /* Any (TCP) */ /* $ man getaddrinfo [...] Given node and service, which identify an Internet host and a service, getaddrinfo() returns one or more addrinfo structures, each of which contains an Internet address that can be specified in a call to bind(2) or connect(2). [...] */ err = getaddrinfo(argv[1], argv[2], &hints, &res); if (err != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err)); exit(EXIT_FAILURE); } /* Loop through the address structures */ for (r = res; r != NULL; r = r->ai_next) { /* Create the socket */ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s < 0) { perror("socket"); continue; } /* Connect to the server */ if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { close(s); perror("connect"); continue; } /* Success */ break; } /* Give up */ if (r == NULL) { fprintf(stderr, "Connecting failed!\n"); exit(EXIT_FAILURE); } /* No longer needed */ freeaddrinfo(res); printf("Connection established...\n"); printf("-------------------------\n"); /* Infinitely offering to send more */ for (;;) { printf("\nType 'y' to send one (more) message: "); c1 = getchar(); c2 = getchar(); if ((c1 == 'y') && (c2 == '\n')) { /* Clear message buffer */ memset(line, 0, sizeof(line)); /* $ man fgets [...] gets() and fgets() return s on success, and NULL on error or when end of file occurs while no characters have been read. [...] */ if (fgets(line, sizeof(line), stdin)) { /* Finally: Send user's message to server */ if (send(s, line, sizeof(line), 0) < 0) { perror("send"); exit(EXIT_FAILURE); } } } else { break; } } printf("\n-----\n"); printf("Exit!\n"); /* Clean up */ shutdown(s, 2); close(s); return EXIT_SUCCESS; }