0% ont trouvé ce document utile (0 vote)
14 vues7 pages

Intro c2

Le document présente une introduction au langage de programmation C, y compris des exemples de code pour un programme simple 'HelloWorld' et un programme réseau 'listener'. Il aborde les concepts de base tels que les variables, les conditions, les boucles, les pointeurs, et la gestion de la mémoire dynamique. Des conseils pratiques pour la programmation réseau et la gestion des erreurs sont également fournis.

Transféré par

talebdjamilaa
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
14 vues7 pages

Intro c2

Le document présente une introduction au langage de programmation C, y compris des exemples de code pour un programme simple 'HelloWorld' et un programme réseau 'listener'. Il aborde les concepts de base tels que les variables, les conditions, les boucles, les pointeurs, et la gestion de la mémoire dynamique. Des conseils pratiques pour la programmation réseau et la gestion des erreurs sont également fournis.

Transféré par

talebdjamilaa
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Premier Programme

tout texte à l’intérieur de /* et */ est un commentaire

HelloWorld.c
/* this is our first C program,
* it will display a message
*/

#include <stdio.h>
importe un fichier
d’en-tete contenant
les définitions de int main()
{
la bibliothèque E/S printf("Hello, World\n");
}

bloc d’instructions délimité par { et }


(corps de fonction, boucle, condition ...)

Figure 1: gcc -Wall HelloWorld.c pour compiler

Introduction au langage C
• langage de programmation impératif, typage faible
• largement utilisé dans la conception/programmation des
systèmes UNIX
caractéristiques
• chaque variable/fonction doit avoir été définie avant de servir
• sources constituées de fichiers de définitions (.h) et de fichiers
d’ implémentation (.c)
• chaque programme possède une fonction principale (main) qui
est appelée par le système
• pas de type “chaı̂ne” : tableaux de caractères + bibliothèques
ouvrage de référence :
• “Le langage C, 2o édition (norme ANSI)”, B.W. Kernighan &
D.M. Ritchie, Prentice Hall (isbn: 2-225-83035-5)

1
Second Programme : l’Écouteur
fichiers :
• listener.c : établissement de la connexion réseau
• receive echo.c : fonction appelée une fois la connexion établie
• minidebug.h : macros pour faciliter la mise au point (compiler
avec l’option NO DEBUG pour la version finale :)

compilation : gcc listener.c receive echo.c -o listener


utilisation :
• lancer le programme (./listener)
• sur une autre console, telnet localhost 12345
• les messages tapés depuis telnet sont répétés par listener

Kit de survie
affectation : variable = expression
• ne pas confondre avec la comparaison d’égalité ==
conditions : if ( expression ) commandes else commandes
• commandes ::= instruction; | { déclarations instructions }
• la partie else est optionnelle
• une expression est vraie si sa valeur 6= 0
• voir aussi switch et test-expr ?if-expr :else-expr
boucles : while ( expression ) commandes
• répète les commandes tant que l’expression est vraie,
• while(1)commandes boucle à l’infini
• voir aussi for, do .. loop, do .. while, break et continue
http://www.linux-kheops.com/doc/ansi-c/

3
Printed by Sylvain Martin
Oct 09, 01 10:11 listener.c Page 1/1
#include <sys/socket.h>
#include <netinet/in.h>
#include "minidebug.h"
#define LOCAL_PORT 12345

void receive_datas(int fd);

main()
{
int masterfd, datafd;
struct sockaddr_in listen_addr={
sin_family: AF_INET, sin_port:htons(LOCAL_PORT)
};
DD("Initialising connection ...\n");
masterfd=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if (masterfd == −1) FATAL("socket");
listen_addr.sin_addr.s_addr=INADDR_ANY;
if (bind(masterfd,(struct sockaddr*)&listen_addr,sizeof(listen_addr))==−1)
FATAL("bind");
listen(masterfd,2);
DD("waiting for a talker on port %i...\n", LOCAL_PORT);
datafd=accept(masterfd,NULL,NULL);
close(masterfd);
DD("ready to receive datas\n");
receive_datas(datafd);
DD("all done\n");
}
Tuesday October 09, 2001 listener.c 1/1

4-2

Printed by Sylvain Martin


Oct 09, 01 10:05 receive_echo.c Page 1/1

void receive_datas(int fd)


{
char buffer[257];
int len=1;

memset(buffer,0,256);
while(len!=0)
{
len=recv(fd,buffer,256,0);
buffer[len]=0;
printf("received: %s\n",buffer);
}
}

Tuesday October 09, 2001 receive_echo.c 1/1

4-1
Autres Remarques ...
paramètres :
• ici, des constantes (LOCAL PORT) → il faut recompiler si on
désire faire tourner le serveur sur un autre port :-(
• si on déclare main(int argc, char* argv[]), on peut
récupérer les arguments de la ligne de commande et s’en servir
comme paramètre.

makefile :
• automatiser le processus de compilation
• pour chaque fichier à générer, une règle donnant la cible, les
dépendances (fichiers utilisés) et les commandes de compilation
• make en ligne de commande pour compiler le tout :)

Remarques ...
listen addr Il s’agit d’une structure contenant les paramètres
nécessaires à bind pour créer le TSAP (adresse IP, no de port, type
d’adresse).
• le champ sin zero doit être initialisé à 0
• le champ sin port doit être passé en network order → htons
• bind attend une structure de type sockaddr → casting
(transtypage) nécessaire (struct sockaddr*)

Locals
masterfd = -1073746664
datafd = 1073795440
sin_family = 2
sin_port = 14640
listen_addr =
sin_addr = s_addr = 0
sin_zero = "\000\000\000\000\000\000\000"

5
Pointeurs
Variables dont la valeur est l’adresse en mémoire d’un autre
élément (variable ou fonction).
Utilité :
• manipulation des chaı̂nes de caractères (=ptr vers un tableau)
• arguments passés par variable : int x; scanf("%i",&x);
• portée dynamique : groupe de variables partagées par un
ensemble limité de fonctions (transmet l’adresse d’un struct
aux fonctions)
• permet la construction de structures complexes (listes, arbres,
etc)
Dangers :
• pas/peu de protection contre les pointeurs mal (pas?) initialisés
• risque de corruption des données

Classes de Stockage
int calls;
void f1(int x)
{ nom classe portée durée
static int ctr=0;
int* iptr=NULL; calls globale prg prg
ctr++; x paramètre fct fct
if (x>0) { ctr statique blc prg
int y=x+1;
calls=calls+y;
y locale bloc bloc
} *iptr dynamique – →free
iptr=malloc(sizeof(int));
}
.text .data heap stack

f1( ), main( ) calls, ctr *iptr x, y, iptr

7
Variables Dynamiques
malloc() et free() permettent d’obtenir de nouveaux blocs de
mémoire pour implémenter des variables dynamiques (cf opérateurs
new et dispose du Pascal). Ces variables ne sont utilisables que
par l’intermédiaire de pointeurs.
utilité ?
pour des variables :
• dont la taille ne peut être déterminée qu’à l’exécution
• dont la durée de vie dépend du ’scénario’ d’exécution

dangers
• la mémoire doit être libérée manuellement
• bugs à retardement si libération d’une “mauvaise” adresse
• risque d’utiliser un pointeur vers une variable libérée

10

Petit exemple: listes liées simples


Contruire une List vide
List=NULL;
Ajouter X en tête de List
X->next=List; List=X;
Trouver une entrée dans la List
for (X=List; X && !good(X); X=X->next);
Retirer X de la List
for (Y=List, Prev=NULL; Y && Y!=X; Y=Y->next) Prev=Y;
if (Y==X) {
if (Prev) Prev->next=Y->next;
else List=Y->next;
}

9
Les Bons Trucs de Tonton Pype
La mémoire sans désespoir
• Evitez les malloc quant c’est possible (char msg[x+y+12])
• setenv MALLOC CHECK 2
• Construisez peu de shm, si possible, shmat avant fork

Evitez les deadlocks


• une communication à travers un PIPE ?
• PTHREAD ERRORCHECK MUTEX pour les irréductibles

Surveillez votre programme


• minidebug.h → qui fait quoi
• segv.c → qui plante où
• strace → tous les appels système à la loupe
• assert(x) → ai-je raison

12

Programmation Réseaux Unix


Pourquoi de la programmation parallèle ?
• plusieurs clients → plusieurs opérations concurrentes
• certaines opérations bloquantes → difficile d’assurer de bons
temps de réponse

Comment procéder ?
• fork() permet de construire un clone du processus courant
• le processus-clone hérite des fichiers, socket de son ’père’
• le clone travaille dans une copie de l’espace-mémoire du père.

Comment les faire communiquer ?


• pipe() et socketpair() pour construire des lignes de
communications entre processus
• signal() et kill() pour envoyer des signaux de contrôle.
• fichiers (attention aux accès concurrents).

11

Vous aimerez peut-être aussi