Skip to content

Instantly share code, notes, and snippets.

@tgalopin
Last active August 29, 2015 14:21
Show Gist options
  • Save tgalopin/589b6adb003dd7a8386b to your computer and use it in GitHub Desktop.
Save tgalopin/589b6adb003dd7a8386b to your computer and use it in GitHub Desktop.

Système – Architecture Client / Serveur

I. Création d'une socket

int socket(int domaine, int type, int protocole)
  • domaine: famille de protocole, méthode d'adressage (AF_INET, AF_UNIX) ;
  • type: type de communication à établir parmi ;
  • protocole: 0: détection, IPPROTO_TCP: TCP, IPPROTO_UDP: UDP ;

II. Communication (int type)

Type de communication à établir parmi:

  • SOCK_DGRAM:
    • communication en mode non connecté
    • préservation des limites de messages
    • protocole sous-jacent dans le domaine Internet : UDP
  • SOCK_STREAM:
    • communications fiables en mode connecté
    • autorisation éventuelle des messages hors-bande
    • protocole sous-jacent dans le domaine Internet : TCP
  • SOCK_RAW:
    • accès aux protocoles de plus bas niveau (IP dans le domaine Internet)

III. Adressage (int domaine)

a. Domaine UNIX (AF_UNIX)

Adressage dans le système de fichiers (sur la même machine). Structure d'adresse:

struct sockaddr_un { short sun_family; char sun_path[108]; };

b. Domaine Internet (AF_INET)

Adressage IP (sur différentes machines).=

  • Structure d'adresse IP:

    struct in_addr { u_long s_addr; };
  • Structure d'adresse Internet (IP + port):

    struct sockaddr_in {
        short sin_family;
        u_short sin_port;
        struct in_addr sin_addr;
        char sin_zero[8];
    };

IV. Mise en place du domaine Internet

a. Préparation de l'adresse

Préparation d'un objet ayant la structure sockaddr_in:

  • détermination de l'adresse Internet de la machine locale
    • gethostname
    • gethostbyname
    • choix de la valeur INADDR_ANY
  • choix du numéro de port :
    • port correspondant à un service déjà existant (getservbyname)
    • port de numéro quelconque >= IPPORT_RESERVED
    • port de numéro choisi par le système (on met 0 dans sin_port)

b. Accès au fichier /etc/hosts

Nom et adresse de la machine locale:

  • int gethostname(char * nom, int length)
  • int gethostid()

c. Caractéristiques de la machine

Structure hostent définie dans <netdb.h>.

struct hostent {
    char * h_name; // nom officiel
    char ** h_aliases; // tableau d’alias pour les noms
    int h_addrtype; // AF_INET ou AF_INET6
    int h_length; // longueur en octets de l’adresse IP
    char ** h_addr_list; // tableau des adresses IP
    #define h_addr h_addr_list[0]
};

Fonctions utiles:

  • struct hostent * gethostbyname(char * nom)
  • struct hostent * gethostbyaddr(char * adresse, int longueur, int type)

d. Récupération de l'adresse Internet

  • int getsockname(int sock, struct sockaddr * p_adr, int * p_length)
  • u_long inet_addr(char * adresse)

e. Association d'une adresse à une socket

int bind (int sock, struct sockaddr * p_adress, int length)
  • int sock : descripteur de socket
  • struct sockaddr * p_adress : pointeur en mémoire sur l'adresse
  • int length : longueur de l'adresse

V. Fonctions utilitaires

a. Conversions d’entiers de format Internet en format ordinateur hôte

#include <netinet/in.h>
unsigned long int ntohl(unsigned long netlong); // network to host long
unsigned long int htonl(unsigned long hostlong); // host to network long
unsigned short int ntohs(unsigned short netshort); // network to host short
unsigned short int htons(unsigned short hostshort); // host to network short

b. Conversions d’adresses

#include <arpa/inet.h>

// Structure adresse réseau > Adresse pointée ({7f000001} > 127.0.0.1)
char * inet_ntoa ( struct in_addr adresse )

// Adresse pointée > Structure adresse réseau (127.0.0.1 > {7f000001})
int inet_aton ( char * cp, struct in_addr * adresse )

// Adresse pointée > Valeur adresse réseau (127.0.0.1 > 7f000001)
unsigned long inet_addr ( char * adresse )

c. Services

Structure servent définie dans <netdb.h>.

struct servent {
    char * s_name; // nom officiel du service
    char ** s_aliases; // tableau d’alias pour les services
    int s_port; // numéro du port
    char * s_protos; // le protocole utilisé
};

Fonctions utiles:

  • struct servent * getservbyname(char * nom, char * proto)
  • struct servent * getservbyport(int port, char * proto)

VI. Mode connecté

a. Serveur

int listen (int sock, int nb);
  • int sock : descripteur de la socket d'écoute
  • int nb : nombre maximal de demandes de connexion pendantes
int accept (int sock, struct sockaddr * p_adr, int * p_lgadr);
  • int sock : descripteur de la socket d'écoute
  • struct sockaddr * p_adr : adresse de la socket connectée
  • int * p_lgadr : pointeur sur taille de la zone allouée à p_adr

b. Client

int connect(int sock, struct sockaddr * p_adr, int lgadr);
  • int sock : descripteur de la socket locale
  • struct sockaddr * p_adr : adresse de la socket distante
  • int lgadr : longueur de l'adresse distante

c. Echange de données

int write(int sock, char * msg, int length);
int read(int sock, char * msg, int length);
  • int sock : descripteur de la socket
  • char * msg : message
  • int length : taille du message

d. Libération des sockets

int close(int sock);

VII. Mode non-connecté

  • Communication par datagrammes (UDP)
  • Dans ce mode :
    • il existe toujours des processus serveurs et des processus clients
    • inutile d’établir une connexion avant d’échanger des données
  • Avant toute chose, le serveur doit obtenir une socket et lui donner une adresse publique (primitives socket et bind)
  • Le client doit, lui, demander à utiliser une socket via la primitive socket

a. Emission de datagrammes

int sendto(
    // descripteur de la socket d'émission
    int sock, 

    // adresse du message à envoyer
    char * msg,

    // longueur du message
    int length,

    // =0 pour le type SOCK_DGRAM
    int option,

    // pointeur sur l’adresse de la socket destinataire
    struct sockaddr * p_dest,

    // longueur de l'adresse de la socket destinataire
    int lengthDest
);

b. Réception de datagrammes

int recvfrom(
    // descripteur de la socket de réception
    int sock, 

    // adresse du message à envoyer
    char * msg,

    // taille de l'espace alloué à l'adresse msg
    int length,

    // 0 ou MSG_PEEK
    int option,

    // pour récupérer l'adresse d'expédition
    struct sockaddr * p_exp,

    // taille de l’espace réservé à p_exp et longueur du résultat
    int * p_lgexp
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment