Communication FIABLE et rapide

Brosske Messages postés 98 Date d'inscription jeudi 25 novembre 2004 Statut Membre Dernière intervention 12 août 2010 - 9 nov. 2007 à 08:43
Brosske Messages postés 98 Date d'inscription jeudi 25 novembre 2004 Statut Membre Dernière intervention 12 août 2010 - 10 nov. 2007 à 08:39
Bonjour,

Je cherche un moyen de communiquer FIABLEMENT et rapidement entre 2 applications (en occurence 1 serveur et 1 client).

J'ai essayé :

- via WinSock
- via SendMessage

mais les 2 méthodes foirent quand on veut envoyer rapidement énormément de données répétitivement. (style 4000 requetes l'un après l'autre). Le Winsock s'enmèle les pédales, pendant le SendMessage fais planter l'application (logique car on vas rédiriger les messages de windows vers notre application).
Quand on utilise le winsock pour une simple application de chat par exemple tout vas bien, mais dès qu'on l'utilise avec un peu plus de "STRESS" ça foire.

Quelqu'un une idée svp ?

je vais faire des tests avec des named pipes, mais ça me semble assez compliqué à programer.

F.M.

13 réponses

Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
9 nov. 2007 à 09:15
quel genre de données échanges-tu ?
a quelle architecture es-tu confronté ?

pour le winsock, passes en winsock 2 (www.vbip.com)
après, je pense que ca dépend du code qui se trouve autour du winsock...

t'as pas la garantie que tes données soient transmises toutes d'un coup...
stockes les données recues en attendant que tu ait tout recu, pour pouvoir traiter la chose.
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
9 nov. 2007 à 09:45
salut,

dans la boucle de tes envois de requêtes tu as bien mis application.doevents ?

++
<hr size="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
9 nov. 2007 à 09:55
Tu dis que winsock n'est pas fiable. winsock se base sur la couche
TCP/IP, c'est à dire ce qui est majoritairement utiliser sur internet.

Crois-tu que si ce n'étais pas fiable comme tu dis, il s'échangerai
plusieurs centaines de TeraOctets chaque jour dans le monde ?????

C'est ta façon de le mettre en oeuvre qui n'est pas fiable. Quelque soit la methode de communication utilisée, il faut laisser le temps au recepteur de recevoir les données.
Dès que le debit devient un peu élevé, il est necessaire de mettre en place un protocole de dialogue synchrone. Ce protocle c'est à toi de l'établir. En gros du style, tu découpe tes données en paquets. Tu envoie un paquet, l'équipement distant te répond qu'il l'a recu correctement, tu peux donc envoyer le paquet suivant.
S'il l'a reçu mais incorrect, tu renvoie le même paquet, s'il l'a pas reçu, ou qu'il ne répond pas, il faut prendre les mesures pour retrouver la communication. Quoiqu'il en soit, tu n'envoie pas le paquet suivant tant que le précédent n'est pas reçu correctement.

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #    http://aide-office-vba.monforum.com/index.php
0
Brosske Messages postés 98 Date d'inscription jeudi 25 novembre 2004 Statut Membre Dernière intervention 12 août 2010 1
9 nov. 2007 à 10:14
Wow ! ça c'est du rapide :)

un peu plus de détails :
* Les applications sont en VB6
* ils tournent tout les 2 sur la même machine
* le mot FIABLE se joue sur le fait que 200 transferts entre serveur et client par seconde fais rater parfois un envoi
* aucun boucle prévue, je fonctionne uniquement sur les evenements DataArrival
* les boucles sont interdit car le serveur devra fonctionner avec encore 3 autres applications (je sais, c'est la méthode bon-marché, mais "stable", de faire du multi-thread)
* quand ça foire j'ai l'impression que côté réception il recoit 2 envois dans le même evenement de réception, exemple : "READYREADY" à la place de "READY" et "READY" dans 2 evenements séparées.
* j'ai déjà signalé ce soucis sous un autre forme sur le forum dans le sens ou les winsock se bloquaient après 3963 envois. Par contre là je fermais à chaque fois la connexion pour l'obliger a envoyer le "READY" et là en effet je n'avais pas le soucis que j'ai ici. A noter qu'après 4 minutes il reprenait là ou il avait laissé l'envoi..... donc de mon point de vue il y a quelque chose qui cloche avec winsock quand on l'innonde de communication (oubien comme casy me dit : que je l'utilise mal).

merci pour vos réponses !!

F.M.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
9 nov. 2007 à 11:23
semble effectivement manquer un appel à DoEvents après tes SendData... ce qui fait que winsock groupe ses tirs... (READYREADY)

au pire, en concevant mieux ton protocole, tu pourrais ne pas te soucier de la chose...

par exemple en ajoutant des témoins debut/fin :

#DEB#READY#FIN##DEB#READY#FIN#

là, tu pourrais traiter tes deux messages de facon distincte...

et supposons que tu recoive :

#DEB#READY#FIN##DEB#REA

tu sais qu'il manque un bout...
0
Brosske Messages postés 98 Date d'inscription jeudi 25 novembre 2004 Statut Membre Dernière intervention 12 août 2010 1
9 nov. 2007 à 11:55
Ben je ne pense pas que c'est çà.....

Voici le code qui s'exécute sur le client après avoir eu la commande de démarrage du serveur:
            Dim Commando As String
            Dim Pos As Integer
            
            SendMessageToTaskManager "IMSDWRBSY"
            MainWindow.Etat.Caption = "après sendBUSY"
            DoEvents
           
            Commando = MSGGetText(HwndTaskManagerDataWriterToDo)
           
            SendMessageToTaskManager "IMSDWRBSY"
            DoEvents
           
            Pos = 1
            MainWindow.TBox(0).Text = Mid(Commando, Pos, InStr(Pos, Commando, "@") - Pos) 'Commande
            Pos = InStr(Pos, Commando, "@") + 1
            MainWindow.TBox(1).Text = Mid(Commando, Pos, InStr(Pos, Commando, "@") - Pos) 'Auteur
            Pos = InStr(Pos, Commando, "@") + 1
            MainWindow.TBox(2).Text = Mid(Commando, Pos, InStr(Pos, Commando, "@") - Pos) 'Zone
            Pos = InStr(Pos, Commando, "@") + 1
            MainWindow.TBox(3).Text = Mid(Commando, Pos, InStr(Pos, Commando, "@") - Pos) 'Atelier
            Pos = InStr(Pos, Commando, "@") + 1
            MainWindow.TBox(4).Text = Mid(Commando, Pos, InStr(Pos, Commando, "@") - Pos) 'Produit
            Pos = InStr(Pos, Commando, "@") + 1
            MainWindow.TBox(5).Text = Mid(Commando, Pos, InStr(Pos, Commando, "@") - Pos) 'Date
            Pos = InStr(Pos, Commando, "@") + 1
            MainWindow.TBox(6).Text = Mid(Commando, Pos, InStr(Pos, Commando, "@") - Pos) 'Heure
            Pos = InStr(Pos, Commando, "@") + 1
            MainWindow.TBox(7).Text = Mid(Commando, Pos, InStr(Pos, Commando, "@") - Pos) 'Anayse-ID
            Pos = InStr(Pos, Commando, "@") + 1
            MainWindow.TBox(8).Text = Mid(Commando, Pos, InStr(Pos, Commando, "@") - Pos) 'Valeur
            Pos = InStr(Pos, Commando, "@") + 1
            MainWindow.TBox(9).Text = Mid(Commando, Pos, InStr(Pos, Commando, "@") - Pos) 'RangeResultat
            Pos = InStr(Pos, Commando, "@") + 1
            MainWindow.TBox(10).Text = Mid(Commando, Pos, InStr(Pos, Commando, "@") - Pos) 'Extrapolation
            Pos = InStr(Pos, Commando, "@") + 1
            MainWindow.TBox(11).Text = Mid(Commando, Pos, InStr(Pos, Commando, "@") - Pos) 'Couleur
            Pos = InStr(Pos, Commando, "@") + 1
            MainWindow.TBox(12).Text = Mid(Commando, Pos, InStr(Pos, Commando, "@") - Pos) 'Exportée
            Pos = InStr(Pos, Commando, "@") + 1
            MainWindow.TBox(14).Text = Mid(Commando, Pos, 100) 'Historique
           
            MainWindow.Etat.Caption = "Requete SQL"
            'DoEvents
            If IsNull(DBM) Then Set DBM = OpenDatabase(DBMainPath)
            Set RSM = DBM.OpenRecordset("Select * From Mesures Where AnalyseID=" & Val(MainWindow.TBox(7).Text) & " And Date=#" & Format(MainWindow.TBox(5).Text, "mm/dd/yyyy") & "# And Heure=#" & Format(MainWindow.TBox(6).Text, "hh:mm:ss") & "#")
            If RSM.RecordCount = 0 Then
                'ErrorHandling "Record not found!"
            Else
                MainWindow.Etat.Caption = "Tentative .Edit"
                On Error Resume Next
                Err.Clear
                RSM.Edit
                If Err.Description <> "" Then
                    'ErrorHandling "Record Locked : " & Err.Description
                    Do
                        Wait (100)
                        Err.Clear
                        RSM.Edit
                    Loop While Err.Number <> 0 'wacht tot we kunnen editeren
                    'ErrorHandling "Record Released."
                End If
                On Error GoTo 0
                                If MainWindow.TBox(8).Text "" Then RSM!Valeur Null Else RSM!Valeur = MainWindow.TBox(8).Text
                RSM!RangeResultat = MainWindow.TBox(9).Text
                RSM!ExtrapolationID = MainWindow.TBox(10).Text
                RSM!Couleur = Val(MainWindow.TBox(10).Text)
                RSM!Exportée = MainWindow.TBox(11).Text
               
                On Error Resume Next
                Err.Clear
                RSM.Update
                If Err.Description <> "" Then
                    'ErrorHandling "Record Locked : " & Err.Description
                    Do
                        Wait (100)
                        Err.Clear
                        RSM.Update
                    Loop While Err.Number <> 0 'wacht tot we kunnen updaten
                    'ErrorHandling "Record Released."
                End If
                On Error GoTo 0
               
                RSH.AddNew
                    RSH!Date = Format(Now, "dd/mm/yyyy")
                    RSH!Heure = Format(Now, "hh:mm:ss")
                    RSH!Login = MainWindow.TBox(1).Text
                    RSH!ADate = MainWindow.TBox(6).Text
                    RSH!AHeure = MainWindow.TBox(6).Text
                    RSH!AnalyseID = MainWindow.TBox(7).Text
                    RSH!Action = MainWindow.TBox(14).Text
                    RSH!Valeur = MainWindow.TBox(8).Text
                RSH.Update
            End If
            RSM.Close
            SendMessageToTaskManager "IMSDWRRDY"
            DoEvents

Donc pas mal de doevents entre 2 non ?

F.M.
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
9 nov. 2007 à 12:14
Pos = InStr(Pos, Commando, "@") + 1
......


utilises Split ^^


que contient : SendMessageToTaskManager ?
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
9 nov. 2007 à 12:16
ah oui, et passes par la CSocket de www.vbip.com

bien plus fiable que la version winsock1 utilisée par VB6
0
Brosske Messages postés 98 Date d'inscription jeudi 25 novembre 2004 Statut Membre Dernière intervention 12 août 2010 1
9 nov. 2007 à 12:47
Split ? hmmm vais me documenter :)

Public Sub SendMessageToTaskManager(ByVal Text As String)
    If IPOut.State <> sckConnected Then
        IPOut.Close
        IPOut.RemoteHost = "localhost"
        IPOut.RemotePort = 4031
        IPOut.Connect
        ConnectionTimeOut.Enabled = True
        Do
            Select Case IPOut.State
                Case 0, 9 'si ne plus connecté, ou en erreur , reconnecter automatiquement
                    IPOut.Close
                    IPOut.RemoteHost = "localhost"
                    IPOut.RemotePort = 4031
                    IPOut.Connect
            End Select
            DoEvents
        Loop While IPOut.State <> sckConnected
        ConnectionTimeOut.Enabled = False
        SendComplete(3) = True
    End If
    If IPIn.State <> sckConnected Then
        IPIn.Close
        IPIn.Listen
    End If
   
    While Not SendComplete(3): DoEvents: Wend
    MainWindow.IPOut.SendData Text
End Sub

F.M.
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
9 nov. 2007 à 14:24
tu passes donc ton temps a te connecter/deconnecter ?

la partie EnsureConnection devrait etre exportée dans une fonction...
pour etre reutilisable facilement, d'une part, et ne pas 'polluer' la fonction SendMessage.

localhost
et
4031

devraient etre remplacés par des constantes... bon reflexe a prendre pour une "configurabilité" accrue et simplifiée plus tard...
0
Brosske Messages postés 98 Date d'inscription jeudi 25 novembre 2004 Statut Membre Dernière intervention 12 août 2010 1
9 nov. 2007 à 15:00
Merci pour les conseils.

Pour la connexion, non elle reste ouverte, mais la routine que je prévois c'est au cas ou elle serait fermé par une raison ou l'autre.
Entre temps j'ai introduit un timer qui , quand le client est trop longtemps BUSY, il renvoi la demande de son état (style après 5 secondes de BUSY). Et là, le client renvoi "READY" et le truc repart..... mais il n'y a pas de raison aparente pourquoi ça se mèle les pédales.....
bizar

je voudrais bien faire un essai avec les pipes, mais ça ne fonctionne pas.........le readfileEx ne prends pas le AddressOf <routinequandreçu> :(

je ne peux pas déposer mon code dans les sources car elle ne fonctionne pas....

F.M.
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
10 nov. 2007 à 02:26
Salut
Les Winsocks sont fiables, c'est garanti.
La couche TCP/IP en mode TCP est fiable aussi puisqu'elle garantit par accusé réception que la donnée est arrivée ET qu'elle est parfaite.
Ce n'est pas le Winsock qui se brèle les pédales, mais ton programme.
Comme l'expliquait RenField (là où il parle de la chaine #DEB#READY#FIN##DEB#READY#FIN# ), il faut toi même insérer des bornes de début et de fin dans chaque 'message' afin de pouvoir décomposer les messages à l'arrivée qui se retrouvent regroupés les uns derrière les autres.
Des tas d'exemples existent sur ces méthodes, il suffit de charger n'importe quelle source de Chat où l'auteur aura pris la peine de gérer cette technique (sources bien notées en général)
Ce phénomène de concaténation des chaines lors de la réception n'est pas dû à un problème de programmation, mais à la charge de ta machine et du temps que tu laisses à la carte mère pour envoyer et acquiérir les infos issues du matériel (d'où l'intérêt des DoEvents).

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
0
Brosske Messages postés 98 Date d'inscription jeudi 25 novembre 2004 Statut Membre Dernière intervention 12 août 2010 1
10 nov. 2007 à 08:39
OK, c'est dommage en sorte qu'ils ne font pas ça en plusieurs étapes.... ben oui : pourquoi il vas coller 2 .SendData différent dans 1 DataArrival.... pas logique de mon point de vue.
2 senddata devraient resulter en 2 évenements différents côté recepteur je trouve :)
mais bon :) qui suis je ....

F.M.
0
Rejoignez-nous