Pertes paquets UDP en VB

Résolu
Signaler
Messages postés
7
Date d'inscription
mardi 11 mars 2003
Statut
Membre
Dernière intervention
30 décembre 2008
-
Messages postés
17288
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
27 septembre 2021
-
Bonjour,

J'utilise le composant Microsoft winsock Control 6 pour une appli client / Serveur. C'est un système d'agents qui envoient des messages à un serveur. L'envoi des messages des agents vers le serveur se fait en UDP. Je sais que le protocole UDP ne donne pas de garantie de livraison, par contre, j'ai, par moment, paquets qui sont apparemment bien reçu sur le serveur quand je regarde le trafic réseau grâce à un tcpdump sur l'interface mais le prog VB semble ne pas les recevoir (pourtant je trace dans un fichier tout ce qui est reçu par ce prog sur la socket avant tout traitement). Avez-vous une idée du pb ? Est-il "normal" que certains paquets puissent arriver au niveau d'une interface et non récupéré par VB ?

Merci d'avance pour votre aide

Voici l'extrait de code VB qui effectue le traitement sur réception :

Private Sub Recv_data_DataArrival(ByVal bytesTotal As Long)
    Dim strdata, suite, msgpret As String
    Dim splt As Variant
    Dim i As Integer
    Dim NomFic As String
   
    On Error GoTo ErrRecept
    NomFic = App.Path & "/mestraces.log" & Format(Now(), "yyyymmdd")
    If NomFic <> NomFicLog Then
        NomFicLog = NomFic
        Close (10)
        Open NomFicLog For Append As #10
    End If
    Recv_data.GetData strdata, vbString
    Print #10, strdata
    suite = ""
    Recv_data.GetData suite, vbString
    strdata = strdata + suite
    While suite <> ""
        Print #10, suite
        suite = ""
        Recv_data.GetData suite, vbString
        strdata = strdata + suite
    Wend
    ..... (après je traite le buffer strdata)
    Exit Sub
ErrRecept:
    ajout_trace "Erreur Trt Message"
    Exit Sub
End Sub

7 réponses

Messages postés
17288
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
27 septembre 2021
71
dangereux de ne fermer qu'une fois ....
tu risque de pas avoir d'infos, si ton appli crash (a verifier)

c'est vraiment couteux de l'ouvri/fermer a chaque log ?

si d'autres données arrivent, tu aura un autre event GetData

utilises le composant Winsock présent ici : www.vbip.com

il est de très bonne facture, et utilise les API Winsock 2, qui sont plus fiables que le composant Winsock classique.
tu aura peu de chose a changer dans ton code pour le mettre en place

Renfield
Admin CodeS-SourceS- MVP Visual Basic
Messages postés
17288
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
27 septembre 2021
71
sais pas si ca viens de ça, mais ici :
Dim strdata, suite, msgpret As String

strdata et suite sont des Variant, non des String

étrange, ton entrecroisement de Close, Open et Print....

remplace tes #10 par la valeur renvoyée par FreeFile avant l'ouverture d'un fichier :

a = FreeFile
Open ... For Append As #a
Print #a,...
Close #a

spécifie la taille que tu soouhaites, dans l'appel a la methode GetData, tu aura normallement plus besoin de boucler pour tout lire

Renfield
Admin CodeS-SourceS- MVP Visual Basic
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
81
Salut
Comme le dit justement RenField, dans la mesure où tu ne spécifies pas de taille/longueur de données que tu lis avec le GetData, TOUTES les données sont lues (comme expliqué dans l'aide), pas la peine de faire deux fois (ou plus) le GetData.
Si d'autres données arrivent ensuite, elles redéclencheront l'évènement DataArrival.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés
Messages postés
7
Date d'inscription
mardi 11 mars 2003
Statut
Membre
Dernière intervention
30 décembre 2008

Salut,

Tout d'abord : merci pour vos réponses rapides. C'est la première fois que je poste une question sur le site et je ne pensais pas que c'était aussi réactif que ça !

Concernant l'entrecroisement de open, close, print : ca me permet de faire une rotation de fichier de log (un fichier généré par jour) car c'est une appli qui tourne en 24/24, 7/7 et qui reçoit un flux relativement important d'informations (donc mon fichier grossit assez vite)
   => Si le jour actuel change, je clos le fichier de log actuellement ouvert et j'en ouvre un nouveau avec la date du jour

La boucle en réception me permet de pallier à une éventuelle limite de taille des données retournées (je crois savoir que le getdata ne renvoie pas plus de 8192 bytes) donc, si le buffer n'est pas complètement vidé (dans le cas de messages supérieurs à 8192 bytes ou si d'autres données sont arrivées entre le déclenchement de l'évènement et la fin du premier getdata), je prend de suite le reste du buffer (j'essaie de me préserver d'un éventuel overload du buffer système de réception UDP en vidant au plus vite ce buffer).

Reste que malgré toutes mes précautions pour prendre absolumment toutes les données du buffer, il y a 2 ou 3 paquets par jour qui ne sont pas récupérés par l'évènement DataArrival et le getdata et je ne vois pas ce que je peux faire pour l'éviter. Si vous avez d'autres idées pour résoudre mon problème...

Merci d'avance
Messages postés
7
Date d'inscription
mardi 11 mars 2003
Statut
Membre
Dernière intervention
30 décembre 2008

Salut,

Merci pour l'info concernant la classe Winsock sur www.vbip.com : je l'avais déjà utilisée une fois dans un autre prog. A ce moment là, elle m'arrangeait mieux que le composant Winsock de chez Microsoft car c'était pour une appli sans interface graphique => Si en plus elle est plus fiable, je vais maintenant prendre l'habitude de n'utiliser que celle-ci...

J'ai modifié le prog en conséquence => je le met 24 heures en test et j'indiquerai sur le site si cette solution est efficace dans ce cas.

Concernant les ouvertures/fermetures de fichier, pour ma part, je n'ai jamais remarqué de problèmes particuliers lorsqu'une de mes applis se crashait sans refermer un fichier de sortie => le buffer était bien flushé.
Dans mon cas, l'appli doit pouvoir supporter une charge maximale en réception de message (ce bout de code sert pour faire de la supervision et généralement quand quelque chose se passe mal, ça se met à envoyer des messages d'alertes de partout !), aussi je ne me permet aucun ordre qui ne soit pas strictement nécessaire pour le fonctionnement et la stabilité de l'appli, d'où la non ouverture/fermeture du fichier à chaque arrivée de message => ça a comme désavantage que je ne suis pas en mesure de voir les derniers messages dans mon log si l'appli tourne mais ce log ne sert justement que si l'appli a rencontré un problème.
Messages postés
7
Date d'inscription
mardi 11 mars 2003
Statut
Membre
Dernière intervention
30 décembre 2008

Salut,

Je viens de faire l'analyse des messages reçus sur ma socket sur une période qui avoisinne les 36 heures : aucune perte de données sur la socket (en général, sur une période comme celle-ci, je perdais environ 3 paquets). La classeWinsock de vbip semble vraiment être plus fiable que le composant de chez Microsoft !

Dorénavant, je prendrais l'habitude de n'utiliser que cette classe...

Merci à tous
Messages postés
17288
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
27 septembre 2021
71
noté...

n'incrimine pas Microsoft, ce sont eux qui sont a l'origine des APIS Winsock et Winsock2....

le composant dispo pour VB n'est juste pas a jour. A ce niveau, oui, on peut les blamer pour négligeance a notre encontre ^^

Renfield
Admin CodeS-SourceS- MVP Visual Basic