IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Quelle classe ou fonction utiliser pour envoyer des messages par TCP IP


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti

    Homme Profil pro
    Ing. dev
    Inscrit en
    Septembre 2009
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing. dev
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2009
    Messages : 29
    Billets dans le blog
    1
    Par défaut Quelle classe ou fonction utiliser pour envoyer des messages par TCP IP
    Bonjour,

    C'est la première fois que je dois faire un projet avec une communication TCP et je ne sais pas qu'elle classe ou fonction utiliser pour arriver à mes fins.

    J'ai un serveur qui ne fait que d'attendre une connexion TCP pour lire une chaine de caractère envoyée sur un port. Le serveur est passif, il ne répond pas après la réception du texte.

    Mon rôle est d'envoyer une chaine de caractère au serveur en étant sur que celui-ci l'ai bien reçu.
    Il y a une contrainte au niveau du temps, je peux me permettre un délai lors de l'établissement de la connexion mais aucun lorsque j'envoie le message.
    Je dois donc gérer séparément la connexion au serveur et l'envoi de messages.
    Lors de la connexion je dois pouvoir modifier un timeout.
    Avant d'envoyer un message je dois être certain que que la connexion est valide.

    J'ai testé les classes TTcpClient et TIdTCPClient mais je n'arrive pas faire ce que j'aimerais.

    Le but final est de créer une DLL qui sera utilisée par Simatic WinCC permettant l'envoi de message.

    J'utilise l'outil de développement C++ Builder 2007.

    Merci d'avance

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 463
    Par défaut
    TCP n'est pas un protocole orienté message.
    Il serait peut-être plus simple d'utiliser un protocole plus adapté à vos contraintes, comme UDP, si vos messages sont de petites tailles.

  3. #3
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Citation Envoyé par bacelar Voir le message
    TCP n'est pas un protocole orienté message.
    C'est vrai: une connexion TCP doit être vue comme un flux in-interrompu de données.
    Si tu veux y ajouter la notion de 'message' (parlons ici de 'blocs' de données), tu vas devoir l'implémenter toi-même.
    Par exemple en décrétant qu'un message se termine systématiquement par un caractère de type 'retour charriot' ('\n' en C/C++).
    Donc ton programme va lire chaque octetreçu sur sa socket et la stocker dans un buffer. Dès qu'il détecte un '\n', il sait qu'il a reçu un bloc complet et peut le passer au reste de l'application pour qu'elle le traite.
    Ton programme vide alors le buffer et recommence pour le message suivant.

    Il serait peut-être plus simple d'utiliser un protocole plus adapté à vos contraintes, comme UDP, si vos messages sont de petites tailles.
    Surtout pas!
    UDP est avant tout un protocole qui autorise la perte de paquets. Si les messages qu'ils envoient doivent tous arriver à destination, TCP est un meilleur choix.

    Il y a une contrainte au niveau du temps, je peux me permettre un délai lors de l'établissement de la connexion mais aucun lorsque j'envoie le message.
    Je te conseille alors de sactiver l'algorithme de Nagle sur ta socket TCP . Tu y gagneras en vitesse au prix d'une légere augmentation de bande passante.

  4. #4
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par bacelar Voir le message
    Il serait peut-être plus simple d'utiliser un protocole plus adapté à vos contraintes, comme UDP, si vos messages sont de petites tailles.
    Mais dans ce cas, le serveur devra impérativement renvoyer un datagramme de confirmation de bonne réception, sachant que ce datagramme peut être lui-même perdu, donc il faut gérer les retransmissions et ignorer les éventuels doublons côté serveur...

    Bref, faut (presque) réimplémenter TCP, donc ce n'est pas forcément optimal côté temps de développement, même si in fine le résultat sera souvent "meilleur" en performances avec de l'UDP.
    Mais bon, quitte à bosser aussi bas, pour ma part je passerais directement en Raw Sockets en m'évitant les couches UDP/IP.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    UDP ne garantie pas l'ordre d'acheminement non plus.

  6. #6
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Bref, faut (presque) réimplémenter TCP, donc ce n'est pas forcément optimal côté temps de développement
    C'est le moins qu'on puisse dire !

    , même si in fine le résultat sera souvent "meilleur" en performances avec de l'UDP.
    Non: un paquet TCP transite aussi vite qu'un paquet UDP. Le seul cas où UDP est plus rapide que TCP c'est si un paquet TCP précédent a été perdu, soit 0.4% des cas pour une transmission internet, et grosso modo moins d'un cas sur un million pour un réseau local LAN filaire. Mais dans ce cas, il faudra encore gérer le désordonnancement des paquets avec UDP (ou même d'abord savoir si ça a un sens au niveau de son appli).

    Mais bon, quitte à bosser aussi bas, pour ma part je passerais directement en Raw Sockets en m'évitant les couches UDP/IP.
    De deux choses l'une:

    - soit c'est pour une transmission dans un réseau local, donc probablement en filaire et donc le TCP fera aussi bien (taux de perte de paquets infime).

    - soit c'est pour une transmission via le net, et un paquet non-TCP et non-UDP ne survivra pas au premier routeur rencontré.

  7. #7
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 463
    Par défaut
    Sur une sémantique message, le cas de perte ou de rejeu est facilement implémentable sans avoir recours à des fenêtre de temporisation, des fenêtre de bufferisation etc...

    TCP/IP donne beaucoup de service mais UDP à un périmètre d'utilisation aussi vaste.

    nouknouk, tes statistiques prennent-t-elles en compte le cout d'établissement et de fermeture de connexion, le problème des démarrage progressif (Nagles) etc... ?

  8. #8
    Membre averti

    Homme Profil pro
    Ing. dev
    Inscrit en
    Septembre 2009
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing. dev
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2009
    Messages : 29
    Billets dans le blog
    1
    Par défaut
    Merci de vos réponses.

    Voici quelques précisions sur vos remarques:

    1 - Je n'ai pas le choix que d'utiliser TCP qui est imposé par le serveur. Celuis-ci est une application achetée où je n'ai aucun pouvoir de modification.
    2 - Le serveur attend des blocs contenant du texte avec un terminateur "\r" pour séparer les diverses chaines.
    3 - Le serveur ne retourne aucun message.
    4 - Nous travaillons sur un réseau LAN et le réseau Internet ne sera jamais utilisé.
    5 - Je n'ai pas besoin d'optimiser à la milli-seconde le protocol. Mais avant d'envoyer un message je dois être sur que la connexion est toujours OK car je dois éviter au maximum de bloquer mon application (DLL) plus de 100ms lors d'un envoi de message.


    En fait j'ai juste besoin :
    - de pouvoir tester si la connexion est réellement valide (Je suis p'être naif, mais je pensais que Connected ou Select de la classe TTcpClient me donnais) en cas de coupure du câble ou autre.
    - de gérer les timeout qui sont actuellement proche des 20s.

    Je vais voir Boost.Asio si ça arrange mes bidons...

  9. #9
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par nouknouk Voir le message
    Non: un paquet TCP transite aussi vite qu'un paquet UDP.
    Pas tout à fait : traverser (logiciellement) la couche TCP est plus long que traverser la couche UDP : pas de machine à états, pas de fenêtres, pas de fragmentation, pas de connexion trois points, etc.

    Attention : soyons bien d'accord, là, on parle de gain très légers (de l'ordre de la microseconde au mieux pour chaque paquet). Sur UN envoi, c'est difficilement mesurable. Sur un transfert soutenu, c'est mesurable, voire significatif.

    Citation Envoyé par nouknouk Voir le message
    - soit c'est pour une transmission dans un réseau local, donc probablement en filaire et donc le TCP fera aussi bien (taux de perte de paquets infime).
    Toujours pareil : ce n'est qu'un problème de temps de traversée de la stack. Pas plus, pas moins.

    Citation Envoyé par nouknouk Voir le message
    - soit c'est pour une transmission via le net, et un paquet non-TCP et non-UDP ne survivra pas au premier routeur rencontré.
    Je n'envisageais pas une seule seconde d'utiliser des raw sockets sur WAN, je te rassure...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  10. #10
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 463
    Par défaut
    Aucun protocole IP ne pourra dire en temps réel si le câble est déconnecté ou pas. C'est pas leur fonction. Débranché le câble ne réinitialisa pas les connexions TCP. Vous le rebranchez en moins de 2 minutes et les connexions sont encore opérationnelles.

    L'approche la plus raisonnable est de faire des envoies non bloquant dans la partie cliente.

  11. #11
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Boost.Asio peut être intéressant, si tu utilises déjà boost par exemple (dans le cas contraire aussi, mais tu seras peut-être plus réticent pour ajouter une bibliothèque à tes dépendances).
    Elle permet de mâcher le travail.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] info pour envoyer des données par mail
    Par boubourse92 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 30/01/2008, 13h04
  2. [C++] quelle structure de donnée utiliser pour stocker des vertices ?
    Par johnnyjohnny dans le forum Développement 2D, 3D et Jeux
    Réponses: 14
    Dernier message: 14/07/2007, 21h44
  3. formulaire pour envoyer des messages.
    Par cyrilmarc dans le forum Langage
    Réponses: 2
    Dernier message: 22/11/2006, 21h15
  4. [Mail] Codage d'une page pour envoyer des messages.
    Par cyrilmarc dans le forum Langage
    Réponses: 5
    Dernier message: 21/11/2006, 21h53
  5. Réponses: 4
    Dernier message: 28/03/2005, 19h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo