Multi-socket client vers plusieurs serveurs différents [Résolu]

surfzoid 467 Messages postés vendredi 15 août 2003Date d'inscription 21 avril 2010 Dernière intervention - 28 nov. 2006 à 19:32 - Dernière réponse : magnus.maximus 22 Messages postés mercredi 15 octobre 2003Date d'inscription 30 mars 2010 Dernière intervention
- 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
Afficher la suite 

Votre réponse

13 réponses

Meilleure réponse
surfzoid 467 Messages postés vendredi 15 août 2003Date d'inscription 21 avril 2010 Dernière intervention - 29 nov. 2006 à 18:48
3
Merci
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

Merci surfzoid 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 74 internautes ce mois-ci

Commenter la réponse de surfzoid
TMONOD 260 Messages postés mardi 25 novembre 2003Date d'inscription 6 novembre 2009 Dernière intervention - 28 nov. 2006 à 20:34
0
Merci
Bonsoir,
As-tu essayé de rechercher le mot "MODBUS" dans le moteur de recherche quelque ligne au dessus ?

Jcbé[^]
Commenter la réponse de TMONOD
cs_casy 7745 Messages postés mercredi 1 septembre 2004Date d'inscription 24 septembre 2014 Dernière intervention - 28 nov. 2006 à 20:36
0
Merci
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.

étape 1 : question serveur 1
étape 2 : attente réponse 1
       réponse arrivé ? oui, passage étape 3, non, reste à l'étape 2
étape 3 : question serveur 2
..................

Si tu as fais du grafset dans ta vie, ça risque de te servir.

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
Commenter la réponse de cs_casy
surfzoid 467 Messages postés vendredi 15 août 2003Date d'inscription 21 avril 2010 Dernière intervention - 29 nov. 2006 à 10:39
0
Merci
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 ...."
@++
Commenter la réponse de surfzoid
cs_casy 7745 Messages postés mercredi 1 septembre 2004Date d'inscription 24 septembre 2014 Dernière intervention - 29 nov. 2006 à 11:19
0
Merci
"...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 #
Commenter la réponse de cs_casy
surfzoid 467 Messages postés vendredi 15 août 2003Date d'inscription 21 avril 2010 Dernière intervention - 29 nov. 2006 à 13:43
0
Merci
"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.
Commenter la réponse de surfzoid
cs_casy 7745 Messages postés mercredi 1 septembre 2004Date d'inscription 24 septembre 2014 Dernière intervention - 29 nov. 2006 à 14:00
0
Merci
Ben essaye comme ça peut-etre (pas de connection réseaux pour tester, juste une ligne internet)

Dim client1 As New TcpClient(server1, port1)
Dim client2 As New TcpClient(server2, port2)

Dim client3 As New TcpClient(server3, port3)

Dim stream1 As NetworkStream = client1.GetStream()
Dim stream2 As NetworkStream = client2.GetStream()

Dim stream3 As NetworkStream = client3.GetStream()

stream1.Write(data, 0, data.Length)
Dim reponse1 As Int32 = stream1.Read(data, 0, data.Length)

stream2.Write(data, 0, data.Length)

Dim reponse2 As Int32 = stream2.Read(data, 0, data.Length)

stream3.Write(data, 0, data.Length)

Dim reponse3 As Int32 = stream3.Read(data, 0, data.Length)

stream1.Close()
stream2.Close()

stream3.Close()

client1.Close()
client2.Close()
client3.Close()

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
Commenter la réponse de cs_casy
surfzoid 467 Messages postés vendredi 15 août 2003Date d'inscription 21 avril 2010 Dernière intervention - 29 nov. 2006 à 14:29
0
Merci
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.
Commenter la réponse de surfzoid
cs_casy 7745 Messages postés mercredi 1 septembre 2004Date d'inscription 24 septembre 2014 Dernière intervention - 29 nov. 2006 à 14:57
0
Merci
L'exemple donné n'est qu'un exemple.

Il te faut déclarer tes sockets en variable globales. Tu les ouvres au début de ton programme, tu les fermes à la fin uniquement.

Durant tout le temps que tu en as besoin, tu les gardes ouverts. Pas besoin de faire de close().

Pour le nombre d'API, regarde du coté des collections, tu pourras faire un indexage de tes sockets.

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
Commenter la réponse de cs_casy
surfzoid 467 Messages postés vendredi 15 août 2003Date d'inscription 21 avril 2010 Dernière intervention - 29 nov. 2006 à 15:32
0
Merci
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).
Commenter la réponse de surfzoid
cs_casy 7745 Messages postés mercredi 1 septembre 2004Date d'inscription 24 septembre 2014 Dernière intervention - 29 nov. 2006 à 18:58
0
Merci
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 #
Commenter la réponse de cs_casy
surfzoid 467 Messages postés vendredi 15 août 2003Date d'inscription 21 avril 2010 Dernière intervention - 29 nov. 2006 à 20:27
0
Merci
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.
@++
Commenter la réponse de surfzoid
magnus.maximus 22 Messages postés mercredi 15 octobre 2003Date d'inscription 30 mars 2010 Dernière intervention - 30 mars 2010 à 22:30
0
Merci
Je vais faire le test sur du Phoenix Contact. Mbus TCP. Ca fait quelques temps que je cherchais cela.
merci
Commenter la réponse de magnus.maximus

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.