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

MFC Discussion :

CSocket ne reçoit plus de notification de réception


Sujet :

MFC

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2008
    Messages : 179
    Par défaut CSocket ne reçoit plus de notification de réception
    Bonjour,

    mon problème a déjà été évoqué, mais la réponse était généralement incomplète ou inadaptée (ou incompréhensive parfois).
    Je la reformule donc à ma sauce, en espérant y trouver une réponse.

    Pour le résumer : le socket ouvert par mon serveur pour gérer la connection à un client reçoit pendant un certain temps des notifications de données disponibles (ie intervention de CSocket::OnReceive()), puis soudainement cesse de recevoir ces notifications. Si j'interviens à ce moment là et que je force par l'appel de 'CSocket::Receive(...,....) la réception, les notifications reprennent, jusqu'à cesser à nouveau un peu plus tard.

    Etant donné que ça me semble être un problème de fond (mauvaise compréhension des sockets MFC en tête de mes suppositions), je ne poste pas le code correspondant ici. A votre demande, je le ferai.
    Pour clarté, je décris mon application plus-bas.

    Est-ce que vous avez une idée du problème ici?
    Est-ce qu'il existe en particulier un moyen "propre" de relancer la machine des notifications sans passer par une rustine inesthétique?

    -------------------------------------------------------------------

    PS : Je précise pour info que lorsque je n'attends pas de confirmation du client ça fonctionne bien (communication à sens unique en somme)... jusqu'à ce que je déborde la pile du client. D'où la raison des messages de confirmation.


    Une petite description de mes applis :

    Mes applications sont de type CLient/Serveur sur protocole TCP (mode connecté "STREAM", sur couche réseau wifi ad-hoc).

    Le client est installé sur un Mac et fonctionne parfaitement (à mon goût en tous cas). Bien qu'adapté pour l'émission et la réception, il est avant tout un récepteur de données (données de gros volumes : plusieurs 100kO)

    le Serveur est installé sur un PC (Windows XP SP2). L'application (View Based) est développée sous Visual Studio 6 et l'API utilisée pour les sockets est celle fournie dans les MFC : CSocket.

    Les données sont échangées sous forme de chaînes d'octets, et des interpréteurs des 2 côtés les traitent jusqu'à présent toujours avec succès (réglant entre autre tous les pbs d'endian).

    L'échange des données se passe de la façon suivante :
    Le client envoie quand ça lui chante des messages textes, que la fonction "OnReceive" de mon Socket Serveur traite en temps "réel".
    Le Serveur envoie initialement un gros paquet de données à traiter puis cesse tout envoie tant qu'il n'a pas reçu de confirmation du client ; le Client de son côté le reçoit, puis envoie une confirmation (message prédéfini) au serveur. Le Serveur continue néanmoins à traiter les messages reçus pendant ce temps (c'est dans ce traitement qu'il identifie la confirmation). Par la suite, le serveur envoie un nouveau gros paquet de données dès qu'il reçoit confirmation de la réception du précédent paquet.

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 492
    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 492
    Par défaut
    TCP, c'est pas terrible pour faire des notifications.
    Vérifiez avec un sniffer réseaux si le problème n'est pas plutôt liée à la configuration de TCP à niveau de la bufferisation coté client.

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2008
    Messages : 179
    Par défaut
    Avant de me lancer dans un reniflage de réseau - pas par paresse* mais parceque je n'ai encore jamais fait celà- je veux être sûr de comprendre le pourquoi...

    Un problème de bufferisation, je suppose que ça veut dire que les données côté Client sont accumulées sans être jamais être envoyées, c'est bien celà?
    Si il y avait un tel problème, l'appel de Receive() forcerait le client à vider sa pile du nombre d'octets demandés?

    Par ailleurs,
    TCP, c'est pas terrible pour faire des notifications.
    .
    Est-ce qu'on parle bien des mêmes notifications ici : je parle pour ma part des messages windows qui déclenchent l'appel de OnReceive(). Mes "confirmations" sont des notifications, dans un sens, mais ce sont bien les notifications windows qui cessent (et du même coup, je ne reçois plus aucune confirmation sauf si je force la lecture avec Receive()).

    Donc si je dois renifler le réseau client, l'idéal est de le faire lorsque je tombe en panne de notifications, afin de confirmer que les messages sont empilés côté Mac et pas perdus en cours de route?


    * : Du reste je viens de passer 30 minutes à essayer d'installer wireshark sur le Mac, et ce n'est pas gagné pour réussir à le faire tourner.

  4. #4
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 492
    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 492
    Par défaut
    Vous pouvez renifler aussi bien sur le serveur que sur le client.
    Le but est de voir comment les données sont transférées entre eux, pas de voir d'éventuels problème réseaux.

    Il est préférable de voir le trafic avant, pendant et après l'incident pour pouvoir les comparer.

    Votre interprétation du terme bufferisation correspond à la mienne.

    TCP est un protocole de type flux qui se prête mal à une sémantique de notification, doit votre eventuel problème de notification.

    TCP contient des mécanismes de gestion de flux, pourquoi ne pas s'en servire ?

    Si c'est pour implémenter un mécanisme de request/response à la HTTP, il faut attendre la réponse à la fin de chaque demande, et configurer la connexion pour ne pas faire de bufferisation pour fait un Keep-alive à la HTTP.

    Avec le trafic réseau, on pourra vérifier si le problème et au niveau de la communication entre le client et le serveur ou s'il est dans le code du serveur.

  5. #5
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2008
    Messages : 179
    Par défaut
    Bon,

    je patauge un petit peu dans la manipulation du renifleur, et dois de plus me plonger dans une couche que j'espérais garder transparence. Au moins je me coucherai moins bête.

    Bien que je n'ai pas fini mon analyse, je poste déjà le résultat du renifleur sur un test.

    Le test réalisé est le suivant :

    • Serveur : XXX.XXX.130.2
    • Client : XXX.XXX.130.1


    (je passe la création des sockets, en mode connecté)

    1. Serveur -> CAsyncSocket::Listen()
    2. Client -> Connect(...,XXX.XXX.130.2,5555)
    3. Serveur -> Accept
    4. Serveur -> CAsyncSocket::OnAccept{Accept(NewCAsyncSocket)}
    5. Serveur -> NewCAsyncSocket::Send(49166 Octets) : en deux Send() (7 octets de header et 49159 de données)
    6. Client -> OnDataAvailable{Récupération du Header de taille fixe, et lecture de n octets, n étant indiqué dans le header}
    7. For(i = 0; i < 10 ; i ++) Client -> Send(Confirmation,SizeOfConfirmation,MSG_OOB) => ça c'est pour forcer l'envoi (du moins je l'espérais : mais ça ne change au final rien)
    8. Serveur -> NewCAsyncSocket::OnReceive() : Read() x 2 : header de taille fixe et Données (taille indiquée dans le header).
    9. Déconnection du tout (déconnection "sauvage" via débuggeur, pas via close())


    Le bàt blesse au 8ème point : je ne reçois ma notification (message windows) que lors de la première réception. Après, c'est comme si plus rien n'était envoyé côté client. Bien que j'ai vérifié côté client que les données soient partis, ils semblent bloqués qqpart (l'analyse du renifleur devraient m'en dire plus, j'espère).

    Le résultat du renifleur au cours de cette expérience (Installé sur le Serveur) est en pièces jointe


    Et petite question en réponse à une question :
    TCP contient des mécanismes de gestion de flux, pourquoi ne pas s'en servire ?
    Euh... lesquels? Et pardon d'avance de cet aveu de profonde méconnaissance.
    Fichiers attachés Fichiers attachés

  6. #6
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 492
    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 492
    Par défaut
    Je pense qu'il y a quelques lagunes au niveau des connaissances réseaux.

    TCP est un protocole transport au niveau 4 du model OSI de l'ISO.
    Il a les caractéristiques d'être orienté connexion et envoie en flux de données.
    Il doit donc avoir un mécanisme de création et de destruction de connexion et il n'y a pas de notion de message, c'est un flux d'octets qui passe par une socket TCP d'en un sans un un autre flux dans l'autre sens.
    Le protocole TCP est responsable du bon acheminement de toutes les octets envoyés d'un coté de la connexion vers l'autre coté.
    Il est lourd (TCP), mais il gère lui même la perte de paquet IP par réémission, la suppression de la duplication des paquet IP, le ré-ordonnancement des données venant des paquet IP qui arrivent dans le désordres etc...
    Dans toutes les tâches qu'il à faire, TCP gère plusieurs fenêtres d'émission et de réception, ainsi que des temporisateur pour ne pas noyer le destinataire des données ou le réseau d'interconnexion avec des données (la bufferisation TCP est l'un des mécanismes utilisés pour faire optimiser le trafic réseau).
    En gros, il attend que le destinataire est acquitté une partie des données avant dans n'envoyer d'autre. La taille des données que peut envoyé l'émetteur sans acquittement du destinataire est appelé : la taille de la fenêtre d'émission.
    Une déconnexion "propre" oblige les deux extrémités à vérifier que toutes les données envoyées par l'un des intervenant ont été lu par l'autre.

    La gestion du flux est intrinsèque au protocole TCP. Cela n'empêche pas que si la couche cliente émettrice envoie trop de données, la socket enverra une erreur car elle n'aura plus assez d'espace pour enregistrer les données avant leur envoies et leur acquittement par le destinataire.

    TCP dispose d'une rustine vise à vis de son mode de fonctionnement en flux.
    Cette rustine est appelée : l'envoie de caractères urgents ou Out Of Band (OOB).
    Ce mécanisme permet d'avoir des envois de données qui peuvent dépasser les données déjà émissent de manière normale. Les données normales forme le flux (la Bande), les données envoyées en Urgence sont hors de la bande (Out Of Bande).
    Cela permet de les lire sans avoir à lire tous les octets envoyés avant.
    Etant donné qu'elles doublent tout le monde, il faut utilise une primitive de lecture spéciales pour les lires. Il est même possible de déterminer la position que ces données auraient dû avoir si elles avaient été envoyées normalement (C'est un espèce de marqueur DANS la bande).

    Le OOB de votre primitive ne fait qu'envoyer des données hors du flux de la connexion. Pour preuve le flag "URG" sur les paquets IP à partir du 74 dans les traces du sniffeur.

    Vous n'êtes pas notifié de la présence dans le flux car il n'y a de données dans le flux mais hors du flux.
    Si je me rappel bien, la lecture du marqueur dans le flux permet de lire les données hors bande comme si elles venaient dans la bande.

    Donc, si vous utilisez TCP, autant utiliser toutes les fonctionnalités qu'il offre (gestion des flux).

    Dans les traces, le client n'envoie jamais de données dans la bande, donc le comportement du serveur me paraît logique.

    Il faut donc enlever le OOB. Voir si cela marche correctement. Sinon, réutilisez le sniffeur pour vérifier qu’il n’y pas de bufferisation sur le client. S’il y a bufferisation, changez ke paramétrage de la socket client pour le désactiver.

    P.S.: le sniffer dispose de toute une panoplie de filtre, cela permet d'avoir que les paquets pertinents pour l'analyse (votre DHCP est un très grand bavard)

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

Discussions similaires

  1. Plus d'affichage de réception sous windows terminal de windows 95
    Par Daetheia dans le forum Windows 2000/Me/98/95
    Réponses: 3
    Dernier message: 25/11/2011, 16h37
  2. Réponses: 10
    Dernier message: 05/05/2010, 09h16
  3. plus de notification en lecture seule
    Par bganata dans le forum Excel
    Réponses: 2
    Dernier message: 15/02/2010, 13h05
  4. CSocket qui saute au bout de quelques réceptions
    Par Deckard666 dans le forum MFC
    Réponses: 2
    Dernier message: 04/04/2007, 11h38

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