Previous Up Next

2  Rappels sockets

Un socket est un point de communication par lequel le processus peut émettre ou recevoir des informations vers ou en provenance d’un autre socket.

2.1  Fichiers d’en-tête

#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h> /* constantes, familles... */
#include <netinet/in.h> /* struct sockaddr_in */
#include <arpa/inet.h>  /* prototypes pour les fonctions dans inet(3N) */
#include <netdb.h>      /* struct hostent */

2.2  Le type sockaddr_in

Une adresse de socket dans la famille Internet est définie par :

struct sockaddr_in {
        short   sin_family;       /* la famille de protocole */
        u_short sin_port;         /* numéro de port */
        struct  in_addr sin_addr; /* adresse IP de la machine */
        char    sin_zero[8];      /* remplissage pour faire 16 octets */
};

L’adresse IP d’une machine (type struct in_addr) est en fait 4 octets, qu’on écrit généralement sous la forme 147.127.64.7.

2.3  Coté client

u_long htonl (u_long hostlong);
u_short htons (u_short hostshort);
struct hostent *gethostbyname (char *name);
int socket (int domain, int type, int protocol);
int connect (int s, struct sockaddr *name, int namelen);

On utilise des sockets dans la famille de protocole Internet, de type stream (fiable, fifo, bi-directionnel), créés par : socket (PF_INET, SOCK_STREAM, 0).

Pour la connexion (serverhost est le nom de la machine que l’on veut contacter, port est le numéro du port sur cette machine) :

{
    int sc;
    struct hostent *sp;
    struct sockaddr_in sins;
    /* Obtention d'information au sujet de la machine `serverhost' */
    sp = gethostbyname (serverhost);
    if (sp == NULL) {
        fprintf (stderr, "gethostbyname: %s not found\n", serverhost);
        exit (1);
    }
    /* Création d'un socket Internet de type stream (fiable, bi-directionnel) */
    sc = socket (PF_INET, SOCK_STREAM, 0);
    if (sc == -1) {
        perror ("socket failed");
        exit (1);
    }
    /* Remplissage de la structure `sins' avec la famille de protocoles Internet,
     * le numéro IP de la machine à contacter et le numéro de port. */
    sins.sin_family = AF_INET;
    memcpy (&sins.sin_addr, sp->h_addr_list[0], sp->h_length);
    sins.sin_port = htons (port);
    /* Tentative d'établissement de la connexion. */
    if (connect (sc, (struct sockaddr *)&sins, sizeof(sins)) == -1) {
        perror ("connect failed");
        exit (1);
    }
}

2.4  Coté serveur

int socket (int domain, int type, int protocol);
int setsockopt (int s, int level, int optname, char *optval, int optlen);
int bind (int s, struct sockaddr *name, int namelen);
int listen (int s, int backlog);
int accept (int s, struct sockaddr *addr, int *addrlen);

Ce qui s’utilise (port est le numéro du port sur lequel écoute le serveur) :

{
    struct sockaddr_in soc_in;
    int val;
    int ss;  /* socket d'écoute */

    /* socket Internet, de type stream (fiable, bi-directionnel) */
    ss = socket (PF_INET, SOCK_STREAM, 0);

    /* Force la réutilisation de l'adresse si non allouée */
    val = 1;
    setsockopt (ss, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));

    /* Nomme le socket: socket inet, port PORT, adresse IP quelconque */
    soc_in.sin_family = AF_INET;
    soc_in.sin_addr.s_addr = htonl (INADDR_ANY);
    soc_in.sin_port = htons (port);
    bind (ss, &soc_in, sizeof(soc_in));

    /* Prépare le socket à la réception de demande de connexions */
    listen (ss, 5);

    while (1) {
        struct sockaddr_in from;
        int len;
        int f;

        /* Accepte une connexion.
         * Les paramètres `from' et `len' peuvent etre NULL. */
        len = sizeof (from);
        f = accept (ss, (struct sockaddr *)&from, &len);

        /* ... */
    }
}

Attention : il manque le traitement d’erreur, qui est indispensable avec les sockets, du fait de la forte probabilité de défaillance.


Previous Up Next