socket_TCP_client_ipv6.c
00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <stdlib.h>
00004 #include <unistd.h>
00005 #include <sys/socket.h>
00006 #include <netinet/in.h>
00007 #include <arpa/inet.h>
00008 #define _POSIX_C_SOURCE 2
00009 #include <netdb.h>
00010
00011 #define MAX_SIZE 256
00012
00013 void error(char * msg) {
00014 perror(msg);
00015 exit(EXIT_FAILURE);
00016 }
00017
00018 void doit(int sockfd, struct addrinfo * serv) {
00019 char requete[MAX_SIZE] = "Luc, je suis ton père!", reponse[MAX_SIZE];
00020 char addr[INET6_ADDRSTRLEN], *ptr = "";
00021 size_t request_size = strlen(requete) + 1;
00022 in_port_t port;
00023
00024 ssize_t n = send(sockfd, requete, request_size, 0);
00025 if (n != request_size) error("[send]");
00026 switch (serv->ai_family) {
00027 case AF_INET: {
00028 struct sockaddr_in *sin = (struct sockaddr_in *) serv->ai_addr;
00029 ptr = (char *) inet_ntop(AF_INET, &sin->sin_addr, addr, sizeof(addr));
00030 port = sin->sin_port;
00031 break; }
00032 case AF_INET6: {
00033 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) serv->ai_addr;
00034 ptr = (char *) inet_ntop(AF_INET6, &sin6->sin6_addr, addr, sizeof(addr));
00035 port = sin6->sin6_port;
00036 break; }
00037 }
00038 if (!ptr) printf("Requête envoyée à %s port %d : <%s> (%ld octets envoyés)\n",
00039 ptr, port, requete, (long) n);
00040
00041 n = recv(sockfd, reponse, MAX_SIZE-1, 0);
00042 if (n < 0) error("[recv]");
00043 reponse[n] = '\0';
00044 printf("Réponse obtenue: <%s> (%lu octets)\n", reponse, (long) n);
00045 }
00046
00047 int main(int argc, char* argv[])
00048 {
00049 char * servname = "localhost";
00050 char * port = "6666";
00051 struct addrinfo hints, *res;
00052 int err, sockfd = -1;
00053
00054 switch (argc) {
00055 case 3: port = argv[2];
00056 case 2: servname = argv[1]; break;
00057 case 1: break;
00058 default: fprintf(stderr, "Usage: %s [servname [port]]\n",argv[0]);
00059 return EXIT_FAILURE;
00060 }
00061
00062 memset(&hints, 0, sizeof(hints));
00063 hints.ai_flags = AI_CANONNAME;
00064 hints.ai_family = AF_UNSPEC;
00065 hints.ai_socktype = SOCK_STREAM;
00066 if ((err = getaddrinfo(servname, port, &hints, &res)) < 0) {
00067 if (err == EAI_SYSTEM) error("[getaddrinfo]");
00068 fprintf(stderr, "[getaddrinfo] on %s : %s\n", servname, gai_strerror(err));
00069 return EXIT_FAILURE;
00070 }
00071 for(; res != NULL; res = res->ai_next) {
00072 sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
00073 if (sockfd < 0) continue;
00074 if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) {
00075 close(sockfd);
00076 sockfd = -1;
00077 continue;
00078 }
00079 break;
00080 }
00081 if (sockfd < 0) error("[socket ou connect]");
00082 doit(sockfd, res);
00083
00084 close(sockfd);
00085 freeaddrinfo(res);
00086 return EXIT_SUCCESS;
00087 }
00088