Jump to content
Sign in to follow this  
AlexMog

[Cours] La programmation réseau

Recommended Posts

Bonjour à tous,

C'est un sujet aussi intéressent que difficile que nous allons voir aujourd'hui: Le réseau.

 

Nous allons découvrir le réseau de manière théorique et pratique, via ce cours.

Nous allons voir tout ça via diverses parties. Tenez-vous bien, après la gestion mémoire, le réseau est la deuxième plus grosse difficulté au niveau de la programmation (ce qui le rends très intéressent!), ce sera un cours principalement théorique (oui, je sais, j'en fais très TRES rarement), et du coup, vous y verrez que très peu de code.

 

Index:

1- Le réseau, en théorie, c'est quoi?

2- En pratique?

3- Différence entre TCP, UDP et UDT (oui oui, ça existe).

4- Quel type de données on peux envoyer en réseau?

5- Synchrone? Asynchrone? Kesako?

6- Un serveur de tchat synchrone (théorique).

7- Notre tchat en version Asynchrone (théorique).

8- Index des fonctions utiles en C (RTFM :)).

 

1- Le réseau, en théorie, c'est quoi?

Le réseau définit un moyen pour deux programmes de pouvoir communiquer. Il existe deux définitions du réseau existantes: LAN et INET. De manière générale, le réseau LAN représente le réseau local (nous ne parlerons pas des réseaux VPN qui sont des exceptions à ce niveau là, puisqu'elles créent un réseau LAN virtuel), et les réseaux dis INET représentent les réseaux passant par internet. WOUHOUUUU!

La partie théorique a l'aire plutôt bien simple! MAIS, et c'est là que le réseau deviens très cool à connaitre, c'est ULTRA-COMPLEXE à comprendre et en même temps pas si compliqué à mettre en place. Je vais donc essayer de ne pas vous perdre durant ce cours.

 

2- En pratique?

Eh oui, la description ci-dessus simplifie pas mal le fonctionnement du réseau au final. Si nous voulons mettre les mains dans le cambouis, il faut savoir pas mal de choses sur le réseau (bien que pas très importantes dans la programmation en elle même, ça vous permettra au moins de comprendre comment fonctionne le réseau de l’intérieur.

Il faut savoir que la couche réseau est la 3ième couche du modèle OSI voyons un peu, pour avoir de la culture info, les 7 couches du modèle OSI:

1- Physique (Le matériel de liaison, carte wifi, blutooth, etc...)

2- Liaison (Gestion de la liaison et de la communication)

3- Réseau (Gestion des couches réseau, IPv4, IPv6, etc...)

4- Transport (Gère la communication en bout des processus, UDP, TCP, etc...)

5- Session (Gère la synchronisation des communications et la gestion des "transactions")

6- Présentation (Code les données applicatives)

7- Application (Définit les points d'accès au service, Nous sommes ICI!)

(je vous conseille de jeter un petit coup d’œil sur Wiki, c'est toujours un plus de savoir ce genre de choses ;), pour vous donner une idée, nous les apprenons par cœur à Epitech (3ième année))

La couche applicative est celle ou nous sommes lorsque nous développons un programme. Toutes les autres couches sont gérées par notre OS, qui fait tout le travail à notre place!

 

Enfin, il faut retenir une chose TRES importante, et qui va beaucoup vous aider: les SOCKETS (système qui permet la communication en réseau) sont des FDs (File descriptors), il sera donc géré comme un fichier, et il faudra toujours penser à FERMER LES SOCKETS! (laisser des FDs ouverts, c'moche! Pauvre kernel :()

 

3- Différence entre TCP, UDP et UDT (oui oui, ça existe).

Ahhh, les protocoles de communication réseau (à ne pas confondre avec les protocoles applicatifs), beaucoup de choix, avec beaucoup de différences.

Nous allons voir ça tout de suite:

1- Le TCP

Le protocole TCP est actuellement le plus stable et certainement le plus utilisé dans le domaine applicatif (ATTENTION: pas dans le jeu-vidéo). Le TCP comporte 3 grand principes:

- Les packets sont certains d'arriver.

- Les packets arrivent dans l'ordre.

- On a une réponse de la réception du packet par le client.

 

Et tout ça, grâce à un header implémenté dans le packet (oui, le packet est un peu plus lourd). Pour résumer, voici ce qui se passe lorsque vous envoyez un packet TCP:

serveur = Envois du packet => client

client = J'ai bien reçu le packet! => serveur

serveur = Ok merci, j'ai bien reçu la réponse! => client

 

Nous voyons donc qu'il y a 3 envois réseau pour chaque packets, ce qui peux ralentir le réseau pour tout ce qui est temps-réel. ATTENTION NEANMOINS, au vue des connexions internet de nos jours, la différence ne se fait pratiquement pas ressentir.

Néanmoins, dans la plupart des jeux, le TCP permet de faire les actions importantes (envois de sorts, pop de monstres, etc...) et l'UDP permet de gérer les actions moins importantes (Déplacements, etc...) pour éviter de surcharger la couche réseau. Même si certains jeux nous montrent bien que le Full TCP, ça peux marcher aussi (RPZ World Of Warcraft).

 

2- L'UDP

L'UDP de manière générale est plus simple, c'est un simple envois de packet ANONYME à un serveur.

Cela offre une vitesse 3 fois plus rapide que le TCP mais néanmoins, on ne sais absolument pas sur le packet est bien arrivé au destinataire.

Il faut donc apprendre à manier le TCP aussi bien que l'UDP en fonction de ce qu'on veux faire.

 

2- L'UDT

Le cas de l'UDT est totalement différent, car c'est un protocole plutôt jeune qui a été créé pour pouvoir transporter un grand nombre de données (on parle ici de Téraoctets) sur un réseau généralement LAN.

Nous n'allons pas en parler ici, mais si vous souhaiter vous renseigner dessus, je vous conseille Wikipedia ;).

 

4- Quel type de données on peux envoyer en réseau?

Là est la question. Pour faire simple, qu'est-ce qui passe par du réseau, en soite? Eh bien, des données en BINAIRE! Eh oui, c'est des 1 et des 0 qui passent dans nos câbles! On s'y attendais pas, hein? Pour résumer, tant que les données peuvent être stockées en mémoire (soite presque toutes), il est possible de les envoyer en réseau (eh oui, c'est pour ça que le réseau est considéré très proche de la gestion mémoire ;)). D'une manière générale, faut pas faire l'imbécile, n'envoyez pas des pointeurs en réseau, puisque l'autre machine, n'aura pas allouée ce pointeur ;). Il faut envoyer des données dites "flat", donc des données et non pas des adresses!

Ce qui est très souvent fait, c'est d'envoyer des structures en réseau. ça permet pas mal de chose, mais c'est très peu modulable.

Une autre technique, c'est de créer un packet.

Voici un exemple du contenu d'un packet:

| taille des données dans le packet (4 octets) | données du packet.... |

du coup, lorsqu'on reçois ce packet, on lit d'abord les 4 premiers octets pour savoir quelle est la taille du packet complet, et on lit le packet ;).

Bref, de la théorie tout ça! On verra dans un autre cours sur le réseau du code à proprement parlé!

 

5- Synchrone? Asynchrone? Kesako?

Le principe de l'Asynchrone et du Synchrone se retrouve souvent dans les applications ayant plusieurs threads (sous processus).

Le principe du Synchrone, c'est d'avoir un thread qui exécute tout de manière Linéaire.

Le principe de l'Asynchrone, c'est d'avoir plusieurs threads, ayant chacun un rôle et communicant entre eux.

Dans notre cas, le Synchrone en réseau est nommé bloquant alors que l'Asynchrone est nommé non bloquant.

Pour faire simple, dans un réseau bloquant, nous attendrons que le client ait bien reçu les informations, alors que dans l'autre cas, nous envoyons les informations en NOWAIT (voir les mans des sockets) et du coup, nous n'attendons pas la réponse TCP. Ce qui nous renvois la taille des données envoyées, et dans le cas ou des données n'ont pas été envoyées, on les renvois.

D'une manière générale, le côté bloquant est utilisé dans les clients, alors que le côté non bloquant est utilisé pour les serveurs (eh oui jamie! Si on est bloquant et qu'un client lag, on fait laguer tout le monde! Exemple concret: Starcraft II, mais là encore l'exemple est spécial, puisque SCII, c'est du P2P via servering).

Pour l'UDP, il n'est pas question d'être bloquant, puisque nous ne savons pas quand le client reçoit l'information.

 

6- Un serveur de tchat synchrone (théorique).

A VENIR.

 

7- Notre tchat en version Asynchrone (théorique).

A VENIR.

 

8- Index des fonctions utiles en C (RTFM :)).

- man 2 socket

- man 2 select (une de mes fonctions préférées en C <3)

- man 2 accept

- man 2 bind

- man 2 connect

- man 2 listen

- man 2 read

- man 2 write

- man 2 recv

- man 2 send

- man 7 ip

- man 7 socket

- man 7 tcp

- man 7 udp

 

A bientôt pour un prochain cours!

 

 

AlexMog.

  • Upvote 7

Share this post


Link to post
Share on other sites

plop,

 

à première vue ça à l'air très complet, et tu reprends des principes de fonctionnements qui ne sont pas forcément propre au C, comme le sync et l'async, c'est vraiment intéressant.

Merci beaucoup ! 

  • Upvote 1

Share this post


Link to post
Share on other sites

plop,

 

à première vue ça à l'air très complet, et tu reprends des principes de fonctionnements qui ne sont pas forcément propre au C, comme le sync et l'async, c'est vraiment intéressant.

Merci beaucoup ! 

Exact, le but étant de faire une grosse introduction au réseau pour pouvoir faire des cours plus variés dessus :).

 

Avec plaisir :).

Share this post


Link to post
Share on other sites

Exact, le but étant de faire une grosse introduction au réseau pour pouvoir faire des cours plus variés dessus :).

 

Avec plaisir :).

 

plop,

 

Tu vas vraiment avoir du travail si tu veux faire des cours sur le réseau, il y a beaucoup de choses complexe à expliquer avant d'arrivé à des choses très intéressantes. Bon courage. 

Share this post


Link to post
Share on other sites

hoo c'est exactement ce que j'étudie !! :)

Donc merci, c'est plus clair que mon cour :P

 

Heureux de t'avoir aidé :)

plop,

 

Tu vas vraiment avoir du travail si tu veux faire des cours sur le réseau, il y a beaucoup de choses complexe à expliquer avant d'arrivé à des choses très intéressantes. Bon courage. 

Je verrais si j'ai la foi :)

  • Upvote 1

Share this post


Link to post
Share on other sites

Excellent tutoriel Alex !
Digne d'un modérateur spécialisé. En plus on me l'avait demandé ce cours là (j'avais omis de transmettre, je crois).

+1 point de réputation, comme d'habitude.

Share this post


Link to post
Share on other sites

Il y a t-il un moyen de réaliser un client-server en tcp ou UDP en quelques lignes? Ou faut-il obligatoirement réaliser toutes la gestion de sockets, les différentes options et tout ça, c'est vite le bordel ;).

Sinon sympa le tutoriel :)

Share this post


Link to post
Share on other sites

Hey,

ça dépendra du langage, et si tu utilises ou non une librairie. Dans tous les cas, faire du network est un challenge, autant que la gestion mémoire, c'est donc souvent une prise de tête, sans parler du débugging en networking qui est... Difficile :)

Share this post


Link to post
Share on other sites

Le réseau est pas aussi compliqué que ont le croix ! moi par exemple je joue un peux avec est j'ai appris tout seul avec du code open source :) après sa peu devenir un casse tête !

Share this post


Link to post
Share on other sites
Le 5/2/2016 à 14:57, aurelien974 a dit :

Le réseau est pas aussi compliqué que ont le croix ! moi par exemple je joue un peux avec est j'ai appris tout seul avec du code open source :) après sa peu devenir un casse tête !

En C# c'est vrai que c'est relativement simple, mais c'est parce-que le framework net facilite beaucoup. En réalité c'est très complexe.

Share this post


Link to post
Share on other sites

il y à pas que C sharp :) le java aussi c'est facile ^^ est en c aussi je trouve ! après c'est pas parce que j'utilise un langage tout le temps sur le forum (C#) que je connais pas d'autre langage ^^ après le Tcp ou l'udp c'est des normes pour que tout les ordinateur communique en semble. tu peux aussi créer ta normes à toi ^^

Le Tcp c'est tout simplement comme une ligne téléphonique.

L'Udp c'est comme si tu envois une lettre que tes pas sûr que le destinataire va recevoir :)

( mais c'est parce-que le framework net facilite beaucoup. En réalité c'est très complexe. ) après je vois pas le problème d'utilisé des outils qui facilite la programmation ^^

Share this post


Link to post
Share on other sites

Mon commentaire s'applique à la plupart des langages populaires car ils possèdent tous une ou plusieurs librairies qui facilite ça.

Et je n'ai jamais dit que c'était un problème, c'est même très bien et je dirais même indispensable.

Share this post


Link to post
Share on other sites

En réalité, c'est encore plus complexe que vous ne le pensez ;). Par exemple, en TCP, la perte d'un packet peut engendrer plusieurs centaines (voir milliers) de MS en ping! Tout ça parce que la liste de packets à envoyer en TCP se rallonge ;). Pour résumer, un packet foireux peut engendrer des secondes de délais si il y en a beaucoup à la chaine.

l'UDP est plutôt facile à comprendre: on envoit une lettre sans être sur qu'elle soit reçue. Mais bon, très compliqué à gérer niveau code. Il faut vérifier que le packet est bien reçu, et qu'il n'est pas corrompu. Bref, un bordel! Souvent on utilise ce qu'on appelle du "Reliable" en UDP, c'est une implémentation qui permet de "tracker" les packets, tout en gardant la puissance de l'UDP.

 

Comprendre, en interne, le TCP et L'UDP est très important. Le TCP est pré-fait avec des systèmes reliables, mais qui ne sont pas forcémment optimisés. (ils le sont pour leur utilité, mais pour un jeu par exemple, le TCP n'est pas conseillé). L'UDP permet, du fait qu'il ne soit pas "connecté" de créer son propre système reliable, et donc d'implémenter sois même un système plus adapté (un des exemples étant l'UDT, qui allie la rapidité de l'UDP avec la force du TCP (je rappelle que l'UDT est encore en dev!)).

 

Bref, quand on a très peu d'experience dans le domaine, on se dit que c'est facile, mais ayant fait mes études très spécialisées là dedans (MSc Network & Network Security) je peux te confirmer que c'est trèèèès compliqué.

 

Question de passage: d'après vous, il vaut mieux envoyer plusieurs "petits" packets en TCP ou un gros packet TCP? (celui qui réponds correctement, je lui dis bravo!)

Share this post


Link to post
Share on other sites

A mon avis, il vaut mieux envoyer un gros packet, ça évite d'avoir à envoyer l'header à chaque fois.

Share this post


Link to post
Share on other sites

Question piège ofc. En faite, ça dépends! Si le packet est trop gros, il sera, dans tous les cas, découpés en "Frames" et envoyé en plusieurs fois ;). Le problème n'étant pas vraiment la taille du packet le problème, mais bien entendu la cadence d'envois ;). En TCP, il ne faut pas oublier qu'on est dans un contexte d'envoit->réception->avis de réception. Donc bon, d'une manière générale, il vaut mieux envoyer un packet "package" avec pas mal d'infos, en TCP, plut^ot que plein de petits :). Le mieux étant encore de respecter les framesizes internationales. Mais bon, là on va un peu trop loin :).

L'UDP, à contrario, est pensé pour l'envoit de plein de petits packets rapidement (en effet, + le packet est gros, + il a de chances d'^etre perdu).

 

Bref, comme je l'ai dis, le réseau est quelque chose de très complexe, et c'est quand on a des app avec des milliers de connexions qu'on commence à s'en rendre compte!

 

Si vous avez d'autres questions, n'hésitez pas!

Share this post


Link to post
Share on other sites

C'est pour ça dans certain code qui utilise du Tcp on voie des sleep un peu partout x') pour pas spam, c'est mieux aussi de découper soie même se que ont veux envoyer ! Est par exemple pour le déplacement d'un personnage en ligne c'est mieux de utiliser du peer-to-peer.

Share this post


Link to post
Share on other sites
Il y a 4 heures, aurelien974 a dit :

C'est pour ça dans certain code qui utilise du Tcp on voie des sleep un peu partout x') pour pas spam, c'est mieux aussi de découper soie même se que ont veux envoyer ! Est par exemple pour le déplacement d'un personnage en ligne c'est mieux de utiliser du peer-to-peer.

Je ne vois pas le rapport du peer to peer avec le découpage des packets. Et pas beaucoup de jeux utilisent le peer to peer.

Share this post


Link to post
Share on other sites

Le découpage est le peet to peer ça pas rapport.

Je voulais juste dire que au lieu d'envoyer un String par exemple qui est très long est l'envoyer comme ça. c'est mieux le découper soie même avent l'envoyer ! 

 

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...