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

VB.NET Discussion :

Préserver l'index d'un objet d'une liste


Sujet :

VB.NET

  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 117
    Par défaut Préserver l'index d'un objet d'une liste
    Bonjour, je cherche à préserver le numéro d'index d'objets tcpclient d'une liste dynamique.

    En effet, comme je li les données des objets tcpclient via la méthode "read" qui est bloquante, si un objet tcpclient est détruit les numéros d'index (supérieur de l'objet détruit) sont décaler.

    Se qui est normale vu que si il y avais 5 objets et qu'un objet (l'index 1) part, le 5eme objet prend donc la place du 4eme au niveau de l'index.

    Comme vous l'aurez compris ceci pose problème au niveau de la méthode read (bloquante) qui elle, li les données d'un index qui n'as plus le même numéro d'index.

    Si une personne a une idée, merci d'avance car je bloque

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par Guyome41 Voir le message
    Comme vous l'aurez compris ceci pose problème au niveau de la méthode read (bloquante) qui elle, li les données d'un index qui n'as plus le même numéro d'index.
    De quelle méthode Read parles-tu ? Et montre ton code, parce que j'ai l'impression que tu t'es un peu emmêlé les pinceaux...

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 117
    Par défaut
    Voici comment l'objet est ajouté :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     ' -----------------------------------------------------------------------
        ' Thread Attente des nouvelles connexions
        ' -----------------------------------------------------------------------
        Private Sub AttenteConnexion()
     
            While 1
                If objClient.Count < ConnMax.Value Then
                    objClient.Add(objServer.AcceptTcpClient())
                    accepter.Add(False)
                    Pseudo.Add("")
                    addr.Add(objClient(objClient.Count - 1).Client.RemoteEndPoint.ToString.Split(CChar(":"))(0))
                    ThConn.Add(New Threading.Thread(AddressOf GestionConnexion))
     
                    If VerifieClient(objClient.Count - 1) <> 0 Then
                        ThConn(ThConn.Count - 1).Start()
     
                    Else
                        objClient(objClient.Count - 1).Close()
                        objClient.Remove(objClient(objClient.Count - 1))
                        accepter.Remove(objClient.Count - 1)
                        Pseudo.Remove(objClient.Count - 1)
                        addr.Remove(objClient.Count - 1)
                    End If
     
                    ' Sinon, on suppérieur au nombre de connexion MAX on met le thread en pause.
                Else
                    Threading.Thread.Sleep(100)
     
                End If
            End While
        End Sub
    Voici la méthode read (avec la boucle) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
                ' Boucle qui maintient la connexion.
                While accepter(i) = True
                    Read = Stream.Read(bytes, 0, bytes.Length)
                    Recu = Encoding.UTF8.GetString(bytes, 0, Read)
                    Dim Donnees() = Recu.Split(vbCrLf)
     
                    ' Boucle avec decoupage des retours chariots de la données recu.
                    For a As Integer = 0 To Donnees.Count - 2
                        Donnees(a) = Donnees(a).Replace(CChar(ChrW(10)), "")
                        If accepter(i) = True Then GestionDonnees(Donnees(a), i)
                    Next a
                End While
     
                ' Sortie de boucle : le client est déconnecté
                Deconnexion(i)
    EDIT:
    L'objet du thread est repéré avec "i" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Dim i As Integer = objClient.Count - 1
            Dim Stream As NetworkStream = objClient(i).GetStream
            Dim bytes(objClient(i).ReceiveBufferSize) As Byte

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    OK, j'ai l'impression que tu t'y prends complètement de travers...

    Tu maintiens 4 listes distinctes pour stocker 4 informations sur chacun de tes clients, c'est ingérable... Pourquoi tu ne crées pas une classe Client pour englober les infos de chacun de tes clients connectés ? Comme ça tu aurais juste besoin d'une List(Of Client), et plutôt que de passer un index à toutes tes méthodes, tu passerais une instance de Client. D'ailleurs GestionConnexion pourrait être une méthode d'instance de Client, comme ça elle n'aurait pas du tout à se préoccuper de l'index du client dans la liste...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    Class Client
     
        Public Property TcpClient As TcpClient
        Public Property Address As String
        Public Property Pseudo As String
        Public Property Accepter As Boolean
     
        Public Sub GestionConnexion()
            ...
        End Sub
     
    End Class
     
    ...
     
                If objClient.Count < ConnMax.Value Then
                    Dim c As TcpClient = objServer.AcceptTcpClient()
                    Dim cli As New TcpClient With
                    {
                        .TcpClient = c,
                        .Accepter = False,
                        .Pseudo = "",
                        .Address = c.Client.RemoteEndPoint.ToString.Split(CChar(":"))(0))
                    }
                    clients.Add(cli)
                    ThConn.Add(New Threading.Thread(AddressOf cli.GestionConnexion))
                    ...

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 117
    Par défaut
    Tu maintiens 4 listes distinctes pour stocker 4 informations sur chacun de tes clients
    Disons que je ne vois pas comment faire autrement étant donné que je doit retrouver les objets clients via un pseudonyme donc j'ai créé des liste "parallèle" pour me repérer avec un index.

    C'est se que j'ai fait pour le même serveur en python (fonctionnel) mais je voudrai le refaire un VB.net.

    Avec t'as méthode je ne vois pas comment repérer un client via un pseudonyme , sont adresse IP ou toute autre informations.

    Edit :
    c'est ingérable...
    Non pas du tous. afin c'est mon avis exemple si un admin veut virer un client :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for a = 0 to Pseudo.count - 1
    If pseudo(a) = participant then vire client(a)
    next a
    Ma méthode reste simple pour gérer les connexions ensuite, en cas de déconnexion il me suffi de virer le même index pour que les listes restes bien parallèle.

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par Guyome41 Voir le message
    Non pas du tous. afin c'est mon avis exemple si un admin veut virer un client :

    for a = 0 to Pseudo.count - 1
    If pseudo(a) = participant then vire client(a)
    next a

    Ma méthode reste simple pour gérer les connexions ensuite, en cas de déconnexion il me suffi de virer le même index pour que les listes restes bien parallèle.
    Je ne pense pas que tu aies compris l'intérêt de la programmation orientée objet... Oui, bien sûr c'est faisable de faire ça avec des listes séparées, mais c'est super galère pour maintenir la cohérence des données. La solution que je te propose est beaucoup plus simple à mon avis...

    Bref, tu fais ce que tu veux, mais si tu tiens à continuer dans cette voie, je ne vois pas de solution simple à ton problème

  7. #7
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 117
    Par défaut
    Je ne pense pas que tu aies compris l'intérêt de la programmation orientée objet...
    De là a dire que j'ai pas compris la programmation orienté objet je suis pas d'accord. Dit le franchement, Guyome41 tu est un boulait arrête de programmer !

    Ensuite on est tous des individus différents qui fonts les choses différemment et on a tous nos facilités et nos difficulté différentes.

    Ma méthode n'est surement pas la meilleur la tienne non plus d'ailleurs et j’espérai que sur ce forum on accepté les différences des autres c'est très rare se genre de forum et il y a surement énormément de façon de faire pour arriver au même résultat.

    Je vais surement prendre un peut de ta méthode mais j'aurai aimé que tu ne prenne pas en compte seulement la deuxième partie de mon dernier poste.

    Sur ceux, merci encore de ta patiente et de m'avoir répondu.

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par Guyome41 Voir le message
    Dit le franchement, Guyome41 tu est un boulait arrête de programmer !
    Je ne dirai pas ça, parce que ce n'est absolument pas ce que je pense...
    C'est juste que la façon dont tu gères ton problème est assez révélatrice de quelqu'un qui n'a pas encore vu l'avantage qu'il peut y avoir à regrouper dans une classe des données qui sont liées les unes aux autres (je peux me tromper, mais en tout cas c'est l'impression que j'ai eue en voyant ton code)

    Citation Envoyé par Guyome41 Voir le message
    Ma méthode n'est surement pas la meilleur la tienne non plus d'ailleurs et j’espérai que sur ce forum on accepté les différences des autres c'est très rare se genre de forum et il y a surement énormément de façon de faire pour arriver au même résultat.
    Il est sans doute possible de le faire avec ta méthode, mais franchement ça me semble compliqué. Si j'ai bien compris ton code, chacun de tes threads va travailler sur le dernier client ajouté à la liste... et comme c'est la même liste, au final ils vont tous travailler sur le même, à moins que quelque chose m'échappe (ce qui est très possible, vu que je n'ai pas vu le code complet). En tous cas, une chose est sûre : chaque thread a besoin d'une info pour savoir client il doit traiter, et cette info ne peut pas être l'index, puisque celui ci va changer quand tu vas modifier la liste. Pour moi les 2 options principales sont les suivantes :
    - utiliser des dictionnaires plutôt que des listes, comme ça tu peux avoir un identifiant unique pour chaque client, qui ne sera pas perturbé par les ajouts et suppressions
    - utiliser une classe comme je l'ai suggéré précédemment, pour regrouper les informations. Dans ce cas le thread n'a pas besoin de connaitre l'index du client à traiter, il lui faut juste l'objet Client qui contient toutes les infos nécessaires

    Citation Envoyé par Guyome41 Voir le message
    j'aurai aimé que tu ne prenne pas en compte seulement la deuxième partie de mon dernier poste.
    Effectivement, j'avais manqué la question dans la première partie...
    Avec t'as méthode je ne vois pas comment repérer un client via un pseudonyme , sont adresse IP ou toute autre informations.
    Tu fais une boucle en vérifiant pour chaque objet Client si le pseudo (ou l'adresse, ou autre) correspond à ce que tu cherches :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Function FindClientByPseudo(ByVal pseudo As String) As Client
        For Each c As Client in clients
            If c.Pseudo = pseudo Then
                Return c
            End If
            Return Nothing ' Pas trouvé
        Next
    End Function
    Tu peux également utiliser Linq :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function FindClientByPseudo(ByVal pseudo As String) As Client
        Return clients.FirstOrDefault(Function(c) c.Pseudo = pseudo)
    End Function

  9. #9
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 117
    Par défaut
    Bonjour, non il ne travail pas tous sur le même client il sont séparés par chaque thread.

    En tous cas, j'ai tous repris le code en utilisant ta façon de faire avec les class et je t'avoue franchement que c'est un plaisir de travailler avec cette façon.

    Non seulement j'ai beaucoup gagné en lignes de codes mais c'est bien plus facile à gérer.

    Se que je connaissais pas c'est "Property" pour déclarer une propriété dans une class et pouvoir ensuite la réutiliser.

    Merci encore.

  10. #10
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 117
    Par défaut
    J'ai encore un petit problème au niveau de la recherche pour chaque (class) "Client" de la liste "Clients"

    Dans ma boucle qui ajoute le client pas de problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
                    Clients.Add(cli)
                    Write("connexion : " + cli.Adresse)
                    ' Verification si le client est autorisé ou non puis lancement d'un new thread suivant l'état.
                    If cli.VerifiClient = 0 Then
                        MsgBox(Me.Clients.Count)
                        Dim th As New Threading.Thread(AddressOf cli.GestionConnexion)
                        th.Start()
    Le MsgBox m'envoi bien "1"

    Par contre dans le nouveau thread cli.GestionConnexion la liste de clients est vide :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Public Class Client
        Public Property Pseudo As String
        Public Property Adresse As String
        Public Property TcpClient As TcpClient
        Public Property Accepter As Boolean
     
     
        Public Sub GestionConnexion()
            MsgBox(Form1.Clients.Count)
    le MsgBox me renvoi "0" donc toutes les boucles qui vont chercher dans la liste clients ne se font pas (normale).

    Pourtant le client est belle et bien ajouté dans la class "Form1" le msgbox me renvoi bien "1".

    Puis le thread pour GestionConnexion() est le bon je récupère bien toutes les propriété et le client est bien géré, j'ai juste un souci pour lire la liste clients de la class Form1 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
                Dim online As String = "ONLINE:"
                For Each c As Client In Form1.Clients
                    online = online + " " + c.Pseudo
                Next
                WriteClient(online)

  11. #11
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    C'est parce que quand tu utilises Form1.Clients, Form1 fait référence à une instance de Form1 différente dans chaque thread. Cette "fonctionnalité" de VB.NET (l'instance par défaut pour les Forms) est une aberration du point de vue POO, je déconseille vivement de l'utiliser. Il vaut mieux manipuler explicitement une instance spécifique de Form1, en la passant en paramètre si nécessaire.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 08/09/2006, 17h21
  2. récupérer un objet dans une liste chainée
    Par marsuwhite dans le forum Langage
    Réponses: 4
    Dernier message: 05/06/2006, 14h05
  3. insertion d'objets dans une liste chainee
    Par mathher dans le forum C++
    Réponses: 8
    Dernier message: 20/04/2006, 16h28
  4. [Swing][JList] Placer un Objet dans une liste
    Par Invité dans le forum Composants
    Réponses: 1
    Dernier message: 17/02/2006, 10h31
  5. Récupérer un objet d'une liste déroulante
    Par Hell dans le forum C++Builder
    Réponses: 2
    Dernier message: 07/01/2005, 14h59

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