Developpez.com - Rubrique C++

Le Club des Développeurs et IT Pro

Cours de programmation réseau en C++

Introduction à une nouvelle série de tutoriel écrits par Bousk

Le 2016-05-18 16:19:09, par Bousk, Rédacteur/Modérateur
Bonjour à tous,

je vous présente un projet que je mène actuellement, à savoir l'écriture d'un cours de programmation réseau, sur l'utilisation de la bibliothèque socket, en C++.
Il s'agit de la version réécrite et améliorée d'un cours que j'ai dispensé aux étudiants de l'ESGI Paris en 2015.
Le but de cette série est de démystifier l'utilisation du réseau et de vous permettre d'en profiter dans vos applications.

Chaque partie présente simplement une composante (connexion, envoi de données…) et vous permet de comprendre son fonctionnement, puis de la mettre en pratique immédiatement, via un TP et des codes sources fournis.
À la fin de cette série, vous serez en possession des briques élémentaires nécessaires à la mise en place d'échanges réseau dans votre programme, sous forme de classes C++ utilisant l'API socket de votre système.

Dans un premier temps, nous apprendrons à appréhender les échanges en TCP, d'abord en tant que simple client, puis comme serveur.
Ensuite nous verrons l'utilisation d'UDP.
L'utilisation de threads et mutex sera également abordée.
Enfin certaines techniques plus spécifiques aux jeux vidéos seront présentées sous forme d'articles, publiés dans la section idoine.

Les articles seront diffusés au fur et à mesure de leur (ré)écriture. Retrouvez-les ci-dessous.
Introduction
TCP
- Premiers pas
- Envoi et réception
- Mise en place du protocole
- Premiers pas en tant que serveur
- Envoi et réception depuis le serveur
- Mode non bloquant pour le client
- Quelle architecture de client visée ?
- Un premier serveur : miniserveur

UDP
- Premiers pas
- Gérer les pertes et duplications d'identifiants
- S'assurer du bon fonctionnement de son code
- Créer son protocole par-dessus UDP
- Découper et réunifier des paquets & création d'un protocole ordonné non fiable
- Envoi de paquets ordonné fiable
- Combiner tous les protocoles : les canaux de communication
- Gérer des connexions entre machines
- Debugger une application en réseau

Jeux
- Un premier jeu : Morpion

Divers
- Multi-threading et mutex
- Bases de la sérialisation
- Sérialisation de bits
- Sérialisation avancée

Retrouvez tous les cours et tutoriels C++ de Developpez.com
  Discussion forum
53 commentaires
  • François DORIN
    Expert éminent sénior
    Bonjour,
    Envoyé par Bousk

    avant de pouvoir écrire la suite du serveur, il convient de voir ce qu'est un thread, un mutex et comment les utiliser.
    Envoyé par Bousk
    De manière générale, il est préférable de construire son application de manière à ce que le code soit synchronisé par construction. En effet, un mutex est un point de contention, utilisé pour que deux tâches ne puissent s'exécuter en parallèle. On verrouillera un mutex pour l'acquérir, les appels successifs ne pourront alors pas le verrouiller et devront attendre qu'il soit libéré. Il s'agit bel et bien d'une attente, donc de bloquer le thread en question.
    Comme je te l'ai déjà signalé, tu présentes les mutex de manière erronée. Un mutex n'est pas fait pour synchroniser des tâches, mais pour éviter des accès concurrents à une "ressource" (une variable, un fichier, un socket, etc...). Il est possible de gérer la synchronisation de plusieurs tâches à l'aide de mutex, mais c'est loin d'être l'utilisation première ! C'est comme planter un clou avec un tournevis. On peut le faire, mais ce n'est pas le plus pratique

    Un mutex est fait pour s'assurer qu'une ressource n'est utilisée que par une et une seule tâche en même temps. Et un bon mutex ne sert à rien 99,9% du temps

    Mais hormis ce point, good tutorial
  • boureb
    Candidat au Club
    Bonjour,
    merci pour ce cour bien utile pour poser les bases.

    Juste un petit problème rencontré lors de la compilation avec Visual Studio 2019 sur Windows 10.

    Le projet TP01 est ok mais à partir du TP02 il faut remplacer:

    Code :
    #if _WIN32_WINNT == _WIN32_WINNT_WINBLUE
    par

    Code :
    #if _WIN32_WINNT >= _WIN32_WINNT_WINBLUE
  • jopopmk
    Membre expert
    Salut,

    petite proposition d'amélioration : montrer la mise en place de macro/commandes prépro pour avoir un code multiplateforme unique. Je suis sûr que ça pourrait intéresser les arpètes qui passeraient sur tes tuto.

    Bonne continuation.

    edit : my bad, j'ai dû lire trop vite ou faire l'impasse sur la partie C++
  • Bousk
    Rédacteur/Modérateur
    Tu as une version compilée avec VS2015 dans Samples/Win10, il faut les redistributables VS2015 pour la lancer.
    Les codes sources sont accessibles via le lien "Télécharger les codes sources du cours" tout en bas de l'article. Un lien a été ajouté plus haut pour plus de clarté.

    Sinon tu peux la recompiler depuis les solutions, VS2013 & VS2015 sont proposées. Elles sont upgradables vers VS2017 sans soucis.
    Il y a un problème avec les versions de Win10 plus récentes, il faut changer les tests #if _WIN32_WINNT == _WIN32_WINNT_WINBLUE en #if _WIN32_WINNT >= _WIN32_WINNT_WINBLUE dams Main.cpp et Clients_Sample/Sockets.hpp
    L'article a été mis à jour avec ces corrections.
  • Bousk
    Rédacteur/Modérateur
    As-tu lu l'article entier ? Pourquoi elle ne fonctionnerait pas ?
    La première moitié de l'article parle et montre les problèmes d'endianness et indique comment les résoudre via des conversions.
    Les implémentations suivantes utilisent ces conversions pour contrer ce problème.
  • Bousk
    Rédacteur/Modérateur
    Salut,

    tu veux dire exactement ce qui est fait dans la seule partie qui le nécessite jusque là ?
    Sinon je vois pas où tu en attends plus.
  • jblecanard
    Membre expert
    Pour aller plus loin, peut-être que ça serait bien d'aborder la "vraie" manière de gérer de multiples connexions côté serveur, à savoir, utiliser les boucles d'événements basées sur epoll, kqueue ou IO Completion Ports. Pourquoi pas en utilisant une bibliothèque qui les abstrait comme libevent.

    Bon c'est vraiment pour la partie la plus avancée du cours, mais ça permet justement de ne pas utiliser de threads .
  • Jordi123
    Candidat au Club
    Super cours, merci pour le partage.
  • Bousk
    Rédacteur/Modérateur
    Hello,
    je viens de revoir toutes les archives des TP TCP et la compilation devrait être correcte sur vs2019. #if _WIN32_WINNT == _WIN32_WINNT_WINBLUE a normalement été remplacé de partout par #if _WIN32_WINNT >= _WIN32_WINNT_WINBLUE. N'hésitez pas à me faire savoir s'il reste une coquille quelque part.
  • Bousk
    Rédacteur/Modérateur
    Non UDP n'est pas une solution pour scaler le miniserveur.
    Pour scaler il faut changer le traitement des connexions et échanges de données (avec kqueue, epoll, .. mentionnés vers le début du thread).
    UDP devrait être utilisé pour du gameplay (temps réel) où le nombre de connexions devrait déjà être limité par les règles gameplay ou les performances nécessaires.

    Pour les lecteurs, je suis désolé du manque de contenus : le temps me manque depuis 3 ans .