Cours 3 : La programmation en mode UDP

 
 
La communication en mode UDP est un mode de communication non fiable, sans connexion. Une fois, les points de communication crées sur la pile de protocole, le client et le serveur s'échangent directement les données sous forme de datagrammes UDP. Chaque envoi doit contenir l'adresse du destinataire.

1 Création des points de communication

 
 
Chaque entité communicante, le client et le serveur, commencent par créer une socket de type SOCK_DGRAM, puis chacun attâche à cette socket son adresse locale, formée du numéro de port de l'application (client ou serveur) et de l' adresse IP des machines client ou serveur.
Fig 2 : Création des points de communication

2 Echange de données en mode UDP

 
 
L'échange de données s'effectuent sous forme de datagrammes. Sa structure est préservée à la réception, c'est-à-dire qu'une opération de réception permet toujours de récupérer l'intégralité d'un datagramme émis sur une opération d'envoi.
 
 
La primitive sendto permet l'envoi d'un datagramme. La primitive recvfrom permet la réception d'un datagramme. La primitive recvfrom est bloquante, c'est-à-dire qu'un processus effectuant un appel à la primitive recvfrom est bloqué jusqu'à avoir effectivement reçu un datagramme.
Fig 3 : Echange de datagrammes
 
 
int sendto(sock, msg, lg, option, p_dest, lgdest)
 
 
 
 
        int sock; -- socket pour l'émission
 
 
        char *msg; -- adresse du message émis
 
 
        int lg; -- taille du message en octets
 
 
        int option;
 
 
        struct sockaddr_in *p_dest; -- adresse du destinataire : adresse IP et n°de port
 
 
        int lgdest; -- taille de la structure d'adresse en octets
 
 
       
 
 
       
 
 
int recvfrom(sock, msg, lg, option, p_exp, lgexp)
 
 
 
 
        int sock; -- socket de réception
 
 
        char *msg; -- adresse d'une zone pour recevoir le message
 
 
        int lg; -- taille en octets de la zone de réception
 
 
        int option; -- 0 ou MSG_PEEK ( le message est lu sans être extrait de la socket)
 
 
        struct sockaddr_in *p_exp; -- structure adresse contenant l'adresse de l'expéditeur du message au retour de la primitive
 
 
         int *lgexp; -- taille de la structure adresse
 
 
Définition : Primitive Sendto
int sendto (int sock, char *msg, int lg, int option, struct sockaddr_in *p_dest, int lgdest) : envoi d'un datagramme msg à *p_dest.
Définition : Primitive Recvfrom
int recvfrom (int sock, char *msg, int lg, int option, struct sockaddr_in *p_exp, int *lgexp) : réception d'un datagramme msg envoyé par *p_exp.

3 Un exemple de programmation en mode UDP

 
 
Nous donnons ci-dessous un exemple de client /serveur en mode UDP. Le client envoie une ligne au serveur qui l'affiche.
CLIENT
 
 
 
 
#include <stdio.h>
 
 
#include <errno.h>
 
 
#include <sys/types.h>
 
 
#include <sys/socket.h>
 
 
#include <netinet/in.h>
 
 
#include <netdb.h>
 
 
 
 
#define PORTC 6259 -- port du client
 
 
#define PORTS  6260  -- port du serveur
 
 
 
 
main()
 
 
 
 
{
 
 
struct hostent *h;
 
 
struct sockaddr_in sin;
 
 
 
 
char buf[20];
 
 
int sock, portc, ports;
 
 
 
 
/* création socket et attâchement d'une adresse*/
 
 
sock = creesock(portc, SOCK_DGRAM)
 
 
 
 
/* Construction adresse du serveur */
 
 
if(!(h=gethostbyname("dirac.cnam.fr")))
 
 
{
 
 
       perror("dirac.cnam.fr");
 
 
       exit(2);
 
 
}
 
 
 
 
bzero(&sin,sizeof(sin));
 
 
sin.sin_family = AF_INET;
 
 
-- copie de l'adresse IP du serveur dans la structure d'adresse sockaddr_in sin
 
 
bcopy(h->h_addr,&sin.sin_addr,h->h_length);
 
 
ports = htons(PORTS);
 
 
sin.sin_port = port s;
 
 
if (sendto(sock, "bonjour, serveur !! ", 20, 0, &sin, sizeof(sin)) == -1)
 
 
{
 
 
       perror ("pb sendto");
 
 
       exit();
 
 
}
 
 
 
 
printf ("Message envoye \n");
 
 
 
 
close (sock);
 
 
}
 
 
     
 
 
      
 
 
     
 
 
     
 
 
 
 
SERVEUR
 
 
 
 
#include <stdio.h>
 
 
#include <sys/types.h>
 
 
#include <sys/socket.h>
 
 
#include <netinet/in.h>
 
 
#include <netdb.h>
 
 
 
 
#define PORTS  6260  -- port du serveur
 
 
 
 
main()
 
 
 
 
{
 
 
int namelen, sock;
 
 
char buf[20];
 
 
struct sockaddr_in adr;
 
 
int lg, n;
 
 
 
 
/* Création socket */
 
 
if((sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0)
 
 
{
 
 
       perror("socket");
 
 
        exit(1);
 
 
}
 
 
 
 
/* preparation de l'adresse */
 
 
/* la zone mémoire pour l'adresse est mise à 0 */
 
 
bzero(&sin,sizeof(sin));
 
 
sin.sin_family = AF_INET;
 
 
sin.sin_port = htons(PORTS) ; /* passage au format réseau */
 
 
sin.sin_addr.s_addr = INADDR_ANY ; /* n'importe quelle adresse IP de la machine locale */
 
 
/* Attâchement socket */
 
 
if(bind(sock, &sin, sizeof(sin)) < 0)
 
 
{
 
 
       perror("bind");
 
 
       exit(2);
 
 
}
 
 
 
 
for (;;)
 
 
{
 
 
   lg = sizeof(adr);
 
 
   n = recvfrom (sock, buf, 20, 0, &adr, &lg);
 
 
   printf("Chaine recu %s\n", buf);
 
 
}
 
 
 
 
close(sock);
 
 
Programmation socket La programmation en mode UDP