surfzoid
Messages postés463Date d'inscriptionvendredi 15 août 2003StatutMembreDernière intervention21 avril 2010
-
28 nov. 2006 à 19:32
magnus.maximus
Messages postés22Date d'inscriptionmercredi 15 octobre 2003StatutMembreDernière intervention30 mars 2010
-
30 mars 2010 à 22:30
J'ai juste une petite question qui me brule les lévres depuis for longtemps, comment faire du multi-socket client vers plusieurs serveurs différents ecoutant sur le port 502 par exemple (comme par hasard,lol), et ensuite une fois toutes les connections établie échanger des données de façon fiable, sans ce mélanger les pinceau sur qui a envoyer les paquets et qui doit les recevoir.
Plus concrétement :
3 serveurs modbus sur le port 502 ayant comme ip 30,31 et 33
1 client qui se connect respectivement a 30,31 et 33
puis en boucle pose une question a 30 et stocke la réponse dans un fichier A, ensuite la même question a 31 et stocke la reponse dans un fichier B et finalement a 33 avec un fichier C et ont recommence depuis le debut sans jamais se déconnecté, si une connection est perdue reconnection et sinon déconnection uniquement lorsqu'on quitte le logiciel?
Je comprendrais aisement qu'on ne reponde pas a ma question tordue car ça fait plus de 6 mois que je bataille avec ça lol :D
surfzoid
Messages postés463Date d'inscriptionvendredi 15 août 2003StatutMembreDernière intervention21 avril 2010 29 nov. 2006 à 18:48
Merci Casy pour ton aide et tes tuyaux extrement précieux, voici donc un petit bout de code test que j'ai écrit, qui me semble raisonnable et pourra servir a d'autre:
Sur une Form Form1 mettre un textbox1, bouton1 et bouton2 ensuite dans le code :
'Casy reconaitra facilement la trame de données envoyée,lol , oui c'est du Modbus lire 100 mots à partir du 100 eme registre.
Imports System.Net
Imports System.Net.Sockets
Public Class Form1
' Declare and create the Collection object.
Public TcpClientColl As New Microsoft.VisualBasic.Collection()
Public NetworkStreamColl As New Microsoft.VisualBasic.Collection()
' Create a new widget and add it to the widgetColl collection.
Private Sub MakeASck(ByVal Server As String) 'Faire un socket client synchronne
Dim TmpTcpClient As New TcpClient(Server, 502)
Dim TmpStream As NetworkStream = TmpTcpClient.GetStream()
TcpClientColl.Add(TmpTcpClient, Server)
NetworkStreamColl.Add(TmpStream, Server)
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Dim i As Integer
For i = 1 To TcpClientColl.Count
TcpClientColl.Item(i).Close()
NetworkStreamColl.Item(i).Close()
Next
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MakeASck(Me.TextBox1.Text)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim i As Integer
Try
For i = 1 To NetworkStreamColl.Count
NetworkStreamColl.Item(i).Write(DataBytes, 0, DataBytes.Length)
Dim Data(211) As Byte
Dim bytes As Int32 = NetworkStreamColl.Item(i).Read(Data, 0, Data.Length)
Next
Catch ex As Exception
TcpClientColl.Remove(i)
NetworkStreamColl.Remove(i)
End Try
End Sub
Private Function DataBytes()
Dim byteArray(11) As [Byte]
byteArray(0) = 15
byteArray(1) = 1
byteArray(2) = 0
byteArray(3) = 0
byteArray(4) = 0
byteArray(5) = 6
byteArray(6) = 1
byteArray(7) = 3
byteArray(8) = 0
byteArray(9) = 100
byteArray(10) = 0
byteArray(11) = 100
Return byteArray
End Function
End Class
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.TextBox1.Text = "192.168.0.33"
End Sub
cs_casy
Messages postés7741Date d'inscriptionmercredi 1 septembre 2004StatutMembreDernière intervention24 septembre 201440 28 nov. 2006 à 20:36
Plus de 6 mois ??? t'es de marseille ???
3 serveurs, 1 client, ça veut dire 3 sockets sur le client, 1 par serveur. soit 3 connections différentes et indépendantes.
si tu sais géréer une connection, tu sait gerer les 3
Ensuite il ne te reste qu'a gerer le point commun entre les 3 connections qui est le séquençage des questions/réponses. Il te suffit de faire un process cyclique comme par exemple un automate d'état pour gerer l'ensemble.
surfzoid
Messages postés463Date d'inscriptionvendredi 15 août 2003StatutMembreDernière intervention21 avril 2010 29 nov. 2006 à 10:39
TMONOD:
Il y a 6 mois j'ai commencé par là mais l'ideal fut www.modbus.org et www.modbus.pl par la suite j'ai plus apporté des reponse sur vbfrance que eut des reponses.
CASY:
Je suis automaticien/supervisor de base donc oui pour le grafcet, lader et logigramme.
Pour l'instant en VB.Net je suis partie sur le composant TcpClient en l'utilisation basiquement avec connection synchrone la seule solution qui fonctionne bien c'est une fonction dans laquelle je donne l'ip de l'automate et je fais dans les grosses lignes
Dim client As New TcpClient(server, port)
Dim stream As NetworkStream = client.GetStream()
stream.Write(data, 0, data.Length)
Dim bytes As Int32 = stream.Read(data, 0, data.Length)
stream.Close()
client.Close()
Cela fonctionne a la perfection avec un PLC Schneider qui a une carte ETY qui gére sans probleme plusieurs client connecté, qui lorsque je dit client.close et/ou streamclose n'est absolument pas perturbé et reste a "l'ecoute" de connecdtion entrantes.
Cependant sur le bureau j'ai aussi un siemens avec un coupleur ethernet (CP 343-1 Lean) qui tourne avec un programme gérant le Modbus Ip grace aux fonction send/receive (FC5 et FC6) seulement voila quand je regarde dynamiquement l'etat du coupleur et que j'envoie mes requettes cyclique je vois sur le coupleur donc :
- En attente de conection passive
- Puis aprés envoi de ma 1 requette :conecté
- Déconnecté
- Et la seulement 5 seconde plus tard En attente de conection passive.
Donc durant ces 5 secondes le coupleur refuse toutes conection, de plus chez siemens il y a la notion de liason configuré qui a pour effet de n'acepté qu'une seule connection cliente.
J'ai fait des tests avec le logiciel que je suis en train d'ecrire directement dans les bureau de Siemens france sur bordeaux, j'ai aussi un "Case" a leur hotline et la seule conclusion c'est de faire du multisocket en gardant une connexion ouverte en permanence, cela est extrement simple a partir de ma méthode citée plus haut en declarant la variable en public dans un module et de dire si client.connected = false then client.connect(server,port)
seulement voila cette optique ne fonctionne pas sur un réseau avec plusieurs automate, car je n'arrive pas a connecté le socket sur une autre ip sans avoir a le fermé et si je le ferme je suis marron pour 5 secondes sachant qu 'il faut beaucoup moins de 5 secondes pour traité 3 Automates ... et que je ne peut pas mettre un temps d'attente de 5 secondes sytematique avant chaque connection car le nombres d'automate n'est pas figée..
Pour conclure, non non je ne suis pas Marseillé lol, cela fait biens 5 ou 6 mois que je planche sur la com Modbus par Serial ou ip et que je m'aventure aussi dans les protocol Siemens, je ne suis pas expert en com mais simplement un autodidact.
Je ne veut pas ecrire un serveur OPC multiprotocol ou reécrire Applicom mais partir sur un system trés basic sans nul besoin de performance extreme.
Merci pour votre intéret que vous portez a mon probleme.
Je suis dans la phase "Au petit bonheur la chance ...."
@++
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_casy
Messages postés7741Date d'inscriptionmercredi 1 septembre 2004StatutMembreDernière intervention24 septembre 201440 29 nov. 2006 à 11:19
"...du multisocket en gardant une connexion ouverte en permanence..." Oui c'est ce que je te disais, 3 serveurs= 3sockets=multisockets
" ...avec plusieurs automate, car je n'arrive pas a connecté le socket sur une autre ip sans avoir a le fermé... " Pas du tout. Tu ne dois pas utiliser le même socket, le fermé et le réouvrir. Il te faut creer 2 autres sockets comme tu as créer le premier, il t'en faut 1 par automate. Il te faut aussi gardé ouvert en permanence les 3 sockets.
---- Sevyc64 (alias Casy) ----<hr size ="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
surfzoid
Messages postés463Date d'inscriptionvendredi 15 août 2003StatutMembreDernière intervention21 avril 2010 29 nov. 2006 à 13:43
"Il te faut creer 2 autres sockets" c'est bien la (diable, lol) que j'ai un serieux probleme de mise en oeuvre, conceptuelement je vois le truc mais en pratique c'est plus un probleme de comment réutilisé un socket existant et/ou comment savoir qu'un socket client sur tel ip est déjas affecter et si il est dejas affecté envoyé des donnée a travers le socket en question ou directement a l'ip du serveur.
surfzoid
Messages postés463Date d'inscriptionvendredi 15 août 2003StatutMembreDernière intervention21 avril 2010 29 nov. 2006 à 14:29
Je suis daccords l idée fonctionne forcement, mais ne reste pas sur l'exemple de 3 API car comme je le disai le nombre d'API n"est pas figée il peut y en avoir de 1 à 50 aujourdh'ui et pourquoi pas demain 51, de plus que je mette 1 ou 3 automate le gros probléme du siemens reste le même :
stream1.Close()
stream2.Close()
stream3.Close()
client1.Close()
client2.Close()
client3.Close()
ICI 5 secondes minimum avant que le siemens n'accepte de nouveau les connection donc au tour de cycle suivant j' ai un echec de connection.
Deplus VB n'est pas aussi "linéaire" qu'un programme Automate.
Ceci dis je continu de fouiller et je m'apercois que en fait pour identifier le socket crée qui se conect sur serveur:502 le composant attribu dynamiquement un port d'ecoute pour les réponses donc ont peut imaginé associer le socket au port pour créer une idée, mais le probleme ensuite c'est que en .Net il n'y as plus les gestionnaires d'evenement commme dataarrival avec winsock en vb6 et encore une fois quand je suis connecté avec par exemple sock1, sock2 et sock3 et que une heure aprés je veut envoyé des données au serveur associé au sock2 par exemple je fais comment pour réassocier un nouveau stream au socket , sachant que le fait de faire stream.close provoque les même reaction au niveau du coupleur siemens a savoir 5 secondes d'attente.
surfzoid
Messages postés463Date d'inscriptionvendredi 15 août 2003StatutMembreDernière intervention21 avril 2010 29 nov. 2006 à 15:32
Quand tu dis "Pas besoin de faire de close()." c'est pour les sockets only ou aussi les stream, les collections je connait pas du tout je vais jetté un oeil (aprés je le récupére bien sur).
cs_casy
Messages postés7741Date d'inscriptionmercredi 1 septembre 2004StatutMembreDernière intervention24 septembre 201440 29 nov. 2006 à 18:58
Ben voila, t'as compris le système et t'as découvert les collections.
Il te restera surrement maintenant à améliorer le système (ex: tu n'utilise pas les données lues) par rapport aux spécificités de ton appli. Mais l'idée y est,j'aurais pas fait mieux. T'es sur la bonne voie.
---- Sevyc64 (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
surfzoid
Messages postés463Date d'inscriptionvendredi 15 août 2003StatutMembreDernière intervention21 avril 2010 29 nov. 2006 à 20:27
Pour les données lues no probleme je travail déjas avec un syteme de cache local dans un fichier XML structuré par adresse API + Valeur, encore merci.
@++