Edit :
Compilateur et terminal en ligne contenant mon code (cliquez sur Compile et Execute dans la barre d'outils en haut à gauche) :
-
Avec l'instruction
connect
commentée : http://goo.gl/Om19VE -
Avec l'instruction
connect
non-commentée : http://goo.gl/Ji6Zlb
==================
Bonjour à tous,
Je veux m'initier à la programmation réseau en C (je précise : pas en C++), et pour ce faire j'ai décidé de récupérer le code HTML du site www.google.fr.
Pour l'instant j'ai écrit un programme qui est censé établir une connexion au serveur de Google qui héberge www.google.fr. Petit problème : l'instruction connect
semble geler mon programme. Quand je retire connect()
, le programme s'exécute bien puis se termine.
Quand connect
est commentée :
-
Le printf-IP s'exécute correctement ;
-
Seule l'erreur shutdown s'affiche : impression de "Erreur shutdown 1" dans la console.
-
Le programme se termine correctement, et tout seul.
Quand connect
n'est pas commentée, plus rien ne s'affiche et le programme est gelé (il semble tourner en boucle) :
-
Le printf-IP n'est plus exécuté ;
-
Aucun printf d'erreur (par exemple le printf-shutdown) n'est exécuté.
-
Le programme ne se termine pas : il semble tourner en boucle, il est gelé.
Par ailleurs, il semblerait que l'IP que j'obtiens ne soit pas la bonne :-/ Cf. le commentaire précédant le printf correspondant.
Qu'est-ce qui ne va pas avec connect
? Voici le code, je l'ai commenté. Merci d'avance !
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | #include <stdio.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #include <stdlib.h> int main (int argc, char** argv) { /* DOCUMENTATION * struct hostent* gethostbyname(const char* name) * struct hostent { * char *h_name; // Nom officiel de l'host * char** h_aliases; // Autres noms de l'host * int h_addrtype; // AF_INET (pour www.google.fr) ou bien AF_INET6 ; type d'adresse de l'host * int h_length; // Longueur en bytes de chaque adresse * char** h_addr_list; // Vecteur des adresses de l'host * char* h_addr; // h_addr_list[0] (première adresse de l'host : celle du serveur) * }; * * * struct in_addr { * unsigned long s_addr; // Y stocker l'IP de l'host, qui est : *p_hostent->h_addr_list[0]) * }; * * * struct sockaddr_in { * short sin_family; // Should be AF_INET (famille spécialisée Internet) * u_short sin_port; // Le port sur lequel l'app est connectée * struct in_addr sin_addr; // Structure contenant l'IP de l'host * char sin_zero; // Not used, must be 0 * }; * * * const char* inet_ntop(int adress_family, const void* source, char* destination, socklen_t size); * * * int socket(int famille, int type, int protocol) * * // sockaddr_in peut être transtypé en sockaddr (car sockaddr est la généralisation de sockaddr_in) * int connect(int socket, const struct sockaddr* address, socklen_t address_len) * * */ // On récupère les infos (notamment les adresses IP) de l'host www.google.fr struct hostent* hostinfo = gethostbyname("www.google.fr"); if (hostinfo == NULL) { printf("Erreur gethostbyname : %d", h_errno); exit(EXIT_FAILURE); } // On stocke la première IP de l'host dans cette structure, structure qui sera utilisée dans sockaddr_in struct in_addr i_a = { *((unsigned long*) hostinfo->h_addr_list[0]) }; // On imprime l'IP, pour s'assurer qu'elle correspond effectivement à celle de www.google.fr (vérifier avec un outil-tier : site Web, etc.) // Résultat : le printf donne 74.125.195.94 et www.mon-ip.com/adresse-ip-site-internet.php donne 216.58.208.227 char string [INET6_ADDRSTRLEN]; const char* i_t = inet_ntop(AF_INET, &i_a.s_addr, string, INET_ADDRSTRLEN); if (i_t == NULL) { printf("Erreur inet_ntop %d", h_errno); exit(EXIT_FAILURE); } printf("\n IP : %s", string); // Sera utilisé dans l'appel à la fonction connect struct sockaddr_in s_i = { AF_INET, 3840, i_a, 0 }; // Création du socket, établissement de la connexion, et fermeture du socket int s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) { printf("Erreur socket %d", h_errno); exit(EXIT_FAILURE); } /* int c = connect(s, (struct sockaddr*) &s_i, sizeof(struct sockaddr)); if (c == -1) { printf("Erreur connect %d", h_errno); exit(EXIT_FAILURE); }*/ int sh = shutdown(s, 2); if (sh == -1) { printf("Erreur shutdown %d", h_errno); exit(EXIT_FAILURE); } return 0; } |