[VB.NET] [Sockets] Crash de mon serveur

Résolu/Fermé
Orci76 Messages postés 92 Date d'inscription lundi 20 décembre 2010 Statut Membre Dernière intervention 21 avril 2015 - Modifié par Orci76 le 29/04/2012 à 15:43
Orci76 Messages postés 92 Date d'inscription lundi 20 décembre 2010 Statut Membre Dernière intervention 21 avril 2015 - 30 avril 2012 à 05:50
Bonjour,
Comme plus ou moins indiqué dans le titre de mon post, mon problème vient des sockets.
Lorsque mon serveur (multithreads) est en mode console, il peut sans problème accueillir pleins de clients (j'ai essayé jusqu'à 25, en local), cependant, lorsque pour des raisons pratiques j'ai voulu transposé mon serveur en WinForm, j'ai été confronté à un problème: il pouvait en effet toujours accueillir plusieurs client, cependant, seuls deux maximums peuvent se connecter en même temps.
Si j'en connecte, c'est bon, si j'en connecte un troisième, le premier s'éteint, un quatrième, le deuxième s'éteint et parfois même deux d'un coup.
J'ai eu beau faire plusieurs essaies désespérés, je ne vois pas d'où cela peut venir. Je vais donc vous mettre mon code source quasi complet ci-dessous (les parties utiles à mes yeux):

Imports System.IO  
Imports System.Net  
Imports System.Text  
Imports System.Net.Sockets  
Imports System.Threading  

Public Class Form1  
    Delegate Sub SetTextCallback(ByVal text As String)  
    Private Sub Message(ByVal text As String)  
        If TextBox1.InvokeRequired Then  
            Dim d As New SetTextCallback(AddressOf Message)  
            Invoke(d, New Object() {text})  
        Else  
            Me.TextBox1.Text &= vbCrLf & text  
        End If  
    End Sub  

    Delegate Sub SetListViewCallback(ByVal p1 As String, ByVal p2 As String)  
    Private Sub ListView(ByVal p1 As String, ByVal p2 As String)  
        Dim SubItemList As ListViewItem = New ListViewItem(New String() {p1, p2})  
        If ListView1.InvokeRequired Then  
            Dim d As New SetListViewCallback(AddressOf ListView)  
            Invoke(d, New Object() {p1, p2})  
        Else  
            ListView1.Items.Add(SubItemList)  
        End If  
    End Sub  

    Private Sub waitForClient()  
        Dim serverSocket As New TcpListener(IPAddress.Parse("127.0.0.1"), 8888)  
        Dim clientSocket As TcpClient  
        Dim counter As Integer  

        serverSocket.Start()  
        counter = 0  
        While (True)  
            counter += 1  
            clientSocket = serverSocket.AcceptTcpClient()  
            Message("Client N°" + Convert.ToString(counter) + " -- Connected!")  
            startClient(clientSocket, Convert.ToString(counter))  
        End While  
        clientSocket.Close()  
        serverSocket.Stop()  
    End Sub  

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load  
        Dim mainThread As Threading.Thread = New Threading.Thread(AddressOf waitForClient)  
        mainThread.Start()  
    End Sub  

    ' ===================================================================================  

    Dim Command As String = "[NONE]"  
    Dim Destinataire As Integer = 0  
    Dim clientSocket As TcpClient  
    Dim clientNumber As String  

    Public Sub startClient(ByVal inClientSocket As TcpClient, ByVal clientNumberF As String)  
        clientSocket = inClientSocket  
        clientNumber = clientNumberF  
        Dim ctThread As Threading.Thread = New Threading.Thread(AddressOf doChat)  
        ctThread.Start()  
    End Sub  

    Private Sub doChat()  
        Dim bytesFrom(10024) As Byte  
        Dim dataFromClient As String  
        Dim sendBytes As [Byte]()  
        Dim serverResponse As String  
        While 1  
            Try  
                Dim networkStream As NetworkStream = clientSocket.GetStream()  
                networkStream.Read(bytesFrom, 0, CInt(clientSocket.ReceiveBufferSize))  
                dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom)  
                dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"))  
                If dataFromClient.Contains("header") Then  
                    Dim strArr() As String  
                    strArr = dataFromClient.Split("|")  
                    ListView(strArr(1), strArr(2))  
                End If  
                If Destinataire = clientNumber Or Destinataire = 0 Then  
                    serverResponse = Command  
                    Command = "[NONE]"  
                    Destinataire = 0  
                Else  
                    serverResponse = "[NONE]"  
                End If  

                sendBytes = Encoding.ASCII.GetBytes(serverResponse)  
                networkStream.Write(sendBytes, 0, sendBytes.Length)  
                networkStream.Flush()  
                If Not serverResponse.Contains("[NONE]") Then  
                    Message("To Client N°" & clientNumber & ": " & serverResponse)  
                End If  
                Thread.Sleep(500)  
            Catch ex As Exception  
                MsgBox(ex.ToString)  
            End Try  
        End While  
    End Sub  
End Class

Pour une question de facilités de lecture, voici un lien PasteBin: https://pastebin.com/xn6SrRQW

Merci d'avance et désolé du dérangement.

2 réponses

Orci76 Messages postés 92 Date d'inscription lundi 20 décembre 2010 Statut Membre Dernière intervention 21 avril 2015 5
30 avril 2012 à 02:41
Up? Si je n'ai pas été assez précis sur un point (je ne vois pas où, mais je connais le problème, dur d'être impartial :x), n'hésitez pas à me demander x)
0
Orci76 Messages postés 92 Date d'inscription lundi 20 décembre 2010 Statut Membre Dernière intervention 21 avril 2015 5
30 avril 2012 à 05:50
Désolé du triple post, c'est seulement pour dire que je résolu mon problème par moi-même ; comment? je ne sais pas vraiment à vrai dire...
J'avais un problème avec la ligne suivante:

ReDim Preserve IDList(IDList.Length + 1)

Je me suis ensuite aperçu en le testant que "IDList.Length" changeait seulement la première fois ( "+1" je suppose) et ensuite gardait sa valeur.
J'en ai donc déduit que c'était limite pour un seul coup (bizarre je trouve d'ailleurs, la valeur n'a pas l'air d'être modifié.
J'ai donc ensuite mis ceci:

ReDim Preserve IDList(IDList.Length + clientNumber)

clientNumber contenant le numéro du client en cours sur le thread (de 1 à X), cela fonctionne maintenant "parfaitement".

PS: Je me suis ensuite renseigné, et d'après ce que j'ai pu voir sur un site, le code suivant permettrait de connaître la dimension d'un tableau dynamique:

Private Function GetUpper(varArray As Variant) As Integer
    Dim Upper As Integer
    On Error Resume Next
    Upper = UBound(varArray)
    If Err.Number Then
        If Err.Number = 9 Then
            Upper = 0
        Else
            With Err
                MsgBox "Error:" & .Number & "-" & .Description
            End With
            Exit Function
        End If
    Else
        Upper = UBound(varArray) + 1
    End If
    On Error GoTo 0
    GetUpper = Upper
End Function

Qu'en pensez vous? laquelle des deux méthodes est la plus rentable? (j'aurais parié pour la mienne, étant donné que je crée ni variable, ni fonction en plus mais que j'arrive tout de même au résultat souhaite).

Merci d'avoir, en espérant que cette histoire de tableau dynamique puisse aider quelqu'un d'autre.
0