ip addr : commande shell loopback : adresse locale (je fais semblant d'utiliser le réseau local mais c'est ma machine que j'utilise) inet : ethernet (celui qu'on utilise) 1) int sock = socket(int domain, int type, int protocol); -> permet de créer la socket domain : AF_INET : IPv4 Internet protocol AF_INET6 : IPv6 Internet protocol -> la famille de protocole utilisée type : SOCK_STREAM : socket de type stream (flux, donc début et fin, vérification de l'arrivée des packets) : fourni une connexion en 2 sens protocol : 0 : le protocole associe par defaut a SOCK_STREAM soit TCP IPPROTO_TCP : défini le protocole TCP close(sock); toujours fermer la socket avant de quitter 2) int connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen); -> permet de connecter la socket référencée par le descripteur de fichier à l'adresse IP indiquée (donc à un serveur donné) Un processus est identifié par : Une adresse IPv4 sur 32 bits (à qui se connecter ?) et un numéro de port sur 16 bits (dans quel service du serveur ?) sockfd : descripteur de fichier (donc le sock qui a été créé -> buffer n°3) serv_addr : adresse IP auquel la socket doit se connecter addrlen : longueur de l'adresse IP en octet (sizeof) 0 : entrée standart 1 : sortie standart 2 : sortie des erreurs 3 : buffer socket struct sockaddr { unsigned short int sa_family; // famille de protocole, par exemple AF_INET unsigned char sa_data[14]; // en fonction de la famille }; struct in_addr { unsigned long int s_addr; // une adresse Ipv4 (32 bits) }; struct sockaddr_in { // si on était en Java, il aurait hérité de sockaddr unsigned short int sin_family; // <- famille de protocole, par exemple AF_INET unsigned short int sin_port; // <- numéro de port // accès à l'endroit exacte de la machine struct in_addr sin_addr; // <- adresse IPv4 (de type in_addr donc en binaire) // accès à la machine }; inet_aton("172.19.32.22", &adresse.sin_addr); -> permet de convertir une adresse IP depuis la notation IPv4 (décimale) vers une forme binaire (dans l'ordre d'octets du réseau) htons() adresse.sin_port = htons(IPPORT_USERRESERVED); // IPPORT_USERRESERVED constante de valeur 5000 (port réservé à l'utilisateur), sinon on a une table des ports réservés -> permet de convertir le numéro de port (qui est sur 16 bits) depuis l'ordre des octets de l'hôte vers celui du réseau l'ordre des octets du réseau est Big Endian (donc il faut appeler les fonctions qui respectent cet ordre pour coder des informations dans les en-têtes des protocoles réseaux) void *memset(void *s, int c, size_t n); -> permet de remplir les n premiers octets de la zone de mémoire pointée par s (&adresse) avec l'octet constant c (0x00 par exemple) if( (connect(sock, (struct sockaddr *)&adresse, longueurAdresse) ) == -1) { // on cast en sockaddr* car &adresse est en sockaddr_in* perror("connect"); close(sock); exit(-2); } résultat : connexion refusée car pas de serveur à qui se connecter donc il faut faire : nc -l -p 5000 // ou IPPORT_USERRESERVED // va attendre une connexion (une demande) ./client-TCP-2 // on retente la connexion résultat : connexion réussie 3)