Application de chat MultiClient/Serveur avec Socket

Résolu
xmahdix - 15 mars 2013 à 21:55
 xmahdix - 16 mars 2013 à 13:17
Bonjour,
j'essaie à réalise une application de chat client/serveur mais toujours ça marche pas, quelqu'un peut me corrigé ce code svp & Merci d'avance :)
Form_Serveur :2 TextBox & 1 Button
Form_Client :2 TextBox & 1 Button




coté Serveur (Class pour les cnx des clients)

Imports System.Net.Sockets
Imports System.IO

Public Class ConnectedClient
    Private cli As TcpClient
    Public Event gotmessage(ByVal message As String, ByVal client As ConnectedClient)    'this is raised when we get a message from the client
    Sub read(ByVal ar As IAsyncResult) 'this will process all messages being recieved
        Try
            Dim sr As New StreamReader(cli.GetStream) 'initialize a new streamreader which will read from the client's stream
            Dim msg As String = sr.ReadLine() 'create a new variable which will be used to hold the message being read
            RaiseEvent gotmessage(msg, Me) 'tell the server a message has been recieved. Me is passed as an argument which represents 
            '                               the current client which it has recieved the message from to perform any client specific
            '                               tasks if needed
            cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'continue reading from the stream
        Catch ex As Exception
            Try 'if an error occurs in the reading purpose, we will try to read again to see if we still can read
                Dim sr As New StreamReader(cli.GetStream) 'initialize a new streamreader which will read from the client's stream
                Dim msg As String = sr.ReadLine() 'create a new variable which will be used to hold the message being read
                RaiseEvent gotmessage(msg, Me) 'tell the server a message has been recieved. Me is passed as an argument which represents 
                '                               the current client which it has recieved the message from to perform any client specific
                '                               tasks if needed
                cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'continue reading from the stream
            Catch ' IF WE STILL CANNOT READ
                
            End Try

        End Try
    End Sub
    Sub senddata(ByVal message As String) 'this is used to deal with sending out messages
        Dim sw As New StreamWriter(cli.GetStream) 'declare a new streamwrite to write to the stream between the client and the server
        sw.WriteLine(message) 'write the message to the stream
        sw.Flush()
    End Sub
    Sub New(ByVal client As TcpClient)

       
        
        cli = client 'assign the client specified to the TCP client variable to we can operate with it
        cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'start reading using the read subroutine

    End Sub
End Class




Coté Serveur Form



Imports System.Net.Sockets
Imports System.Text
Imports System.Net

Public Class Form1
    Dim clients As New Hashtable 'new database (hashtable) to hold the clients

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim listener As New System.Threading.Thread(AddressOf listen) 'initialize a new thread for the listener so our GUI doesn't lag
        listener.IsBackground = True
        listener.Start(8888) 'start the listener, with the port specified as a parameter (textbox1 is our port textbox)

    End Sub
    Sub listen(ByVal port As Integer)
        Try
            Dim t As New TcpListener(IPAddress.Any, 8888) 'declare a new tcplistener
            t.Start() 'start the listener
            Do

                Dim client As New ConnectedClient(t.AcceptTcpClient) 'initialize a new connected client
                AddHandler client.gotmessage, AddressOf recieved 'add the handler which will raise an event when a message is recieved
                'AddHandler client.disconnected, AddressOf disconnected 'add the handler which will raise an event when the client disconnects

            Loop Until False
        Catch
        End Try

    End Sub


    Sub recieved(ByVal msg As String, ByVal client As ConnectedClient)
        'Dim message() As String = msg.Split("|") 'make an array with elements of the message recieved
        ' Select Case message(0) 'process by the first element in the array
        'Case "CHAT" 'if it's CHAT
        '  TextBox3.Text &= client.name & " says: " & " " & message(1) & vbNewLine 'add the message to the chatbox
        '  sendallbutone(message(1), client.name) 'this will update all clients with the new message
        '                                       and it will not send the message to the client it recieved it from :)
        ' Case "LOGIN" 'A client has connected
        '    clients.Add(client, client.name) 'add the client to our database (a hashtable)
        '    ListBox1.Items.Add(client.name) 'add the client to the listbox to display the new user
        ' End Select
        TextBox1.Text &= msg & vbNewLine
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        senddata(TextBox2.Text) 'send teh data with CHAT as the header so the clietn knows to process the message as a chat message
        TextBox1.Text &= "You Say: " & " " & TextBox2.Text & vbNewLine 'add a message to the chat textbox showing we have sent a public message
    End Sub
    Sub senddata(ByVal message As String) 'this sends a message to all connected clients
        Dim entry As DictionaryEntry 'declare a variable of type dictionary entry
        Try
            For Each entry In clients 'for each dictionary entry in the hashtable with all clients (clients)
                Dim cli As ConnectedClient = CType(entry.Key, ConnectedClient) ' cast the hashtable entry to a connection class
                cli.senddata(message) 'send the message to it
            Next  'go to the next client
        Catch
        End Try

    End Sub

End Class






Coté Client


   Dim stream As NetworkStream
    Dim listenThread As System.Threading.Thread

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        client.Connect("127.0.0.1", 8888)

        Try
            If client.Connected Then
                TextBox1.Text = "Connecté"
                stream = client.GetStream()
                Dim ctThread As Threading.Thread = New Threading.Thread(AddressOf getMessage)
                ctThread.Start()
            End If

        Catch ex As Exception
            TextBox1.Text = "not connected"
        End Try

    End Sub
    Private Sub getMessage()
        Do
            stream = client.GetStream()
            Dim buffSize As Integer
            Dim inStream(10024) As Byte
            buffSize = client.ReceiveBufferSize
            stream.Read(inStream, 0, buffSize)
            Dim returndata As String = _
            System.Text.Encoding.ASCII.GetString(inStream)
            msg("" + returndata)

        Loop
    End Sub
    Private Sub msg(ByVal x As String)
        TextBox1.Text = TextBox1.Text + Environment.NewLine + " >> " + x

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim sw As New StreamWriter(client.GetStream) 'declare a new streamwriter
        sw.WriteLine(TextBox2.Text) 'write the message
        sw.Flush()
        TextBox1.Text &= "You: " & " " & TextBox2.Text & vbNewLine
    End Sub
End Class

8 réponses

Utilisateur anonyme
16 mars 2013 à 09:56
Etant oisif ce matin, j'ai mis le nez dans ton code.
Ton serveur (ConnectedClient) et ton Textbox(Form1 : thread principal) sont sur deux threads distincts. Tu dois gérer les opérations inter-threads.
Rajoute un délégué sur ton formulaire Form1 :
Delegate Sub MonDelegue(ByVal msg As String, ByVal client As ConnectedClient)

Puis lorsque tu voudras afficher les données issues de l'autre thread dans ton textbox, il faudra tester s'il est nécessaire d'appeler le délégué ou pas :
If textbox1.InvokeRequired Then
   textbox1.Invoke(New MonDelegue(AddressOf recieved), msg, client)
Else
   TextBox1.Text &= msg & vbNewLine
End If
3
Utilisateur anonyme
16 mars 2013 à 01:38
Salut,

ça marche pas

J'ai tenté de deviner ce qui marche pas mais ça marche pas.
0
Utilisateur anonyme
16 mars 2013 à 01:59
Bonjour,

J'ai tenté de deviner ce qui marche pas mais ça marche pas.
0
Merci pour ton réponse mais toujours le même problème rien a été envoyé et rien a été reçut
0

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

Posez votre question
Utilisateur anonyme
16 mars 2013 à 12:28
Tu n'as pas du bien comprendre mon explication. Montre le code modifié de Form1.
0
Voila

Imports System.Net.Sockets
Imports System.Text
Imports System.Net

Public Class Form1
    Delegate Sub MonDelegue(ByVal msg As String, ByVal client As ConnectedClient)
    Dim clients As New Hashtable 'new database (hashtable) to hold the clients

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim listener As New System.Threading.Thread(AddressOf listen) 'initialize a new thread for the listener so our GUI doesn't lag
        listener.IsBackground = True
        listener.Start(8888) 'start the listener, with the port specified as a parameter (textbox1 is our port textbox)

    End Sub
    Sub listen(ByVal port As Integer)
        Try
            Dim t As New TcpListener(IPAddress.Any, 8888) 'declare a new tcplistener
            t.Start() 'start the listener
            Do

                Dim client As New ConnectedClient(t.AcceptTcpClient) 'initialize a new connected client
                AddHandler client.gotmessage, AddressOf recieved 'add the handler which will raise an event when a message is recieved
                'AddHandler client.disconnected, AddressOf disconnected 'add the handler which will raise an event when the client disconnects

            Loop Until False
        Catch
        End Try

    End Sub


    Sub recieved(ByVal msg As String, ByVal client As ConnectedClient)
        'Dim message() As String = msg.Split("|") 'make an array with elements of the message recieved
        ' Select Case message(0) 'process by the first element in the array
        'Case "CHAT" 'if it's CHAT
        '  TextBox3.Text &= client.name & " says: " & " " & message(1) & vbNewLine 'add the message to the chatbox
        '  sendallbutone(message(1), client.name) 'this will update all clients with the new message
        '                                       and it will not send the message to the client it recieved it from :)
        ' Case "LOGIN" 'A client has connected
        '    clients.Add(client, client.name) 'add the client to our database (a hashtable)
        '    ListBox1.Items.Add(client.name) 'add the client to the listbox to display the new user
        ' End Select

        If TextBox1.InvokeRequired Then
            TextBox1.Invoke(New MonDelegue(AddressOf recieved), msg, client)
        Else
            TextBox1.Text &= msg & vbNewLine
        End If
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        senddata(TextBox2.Text) 'send teh data with CHAT as the header so the clietn knows to process the message as a chat message
        TextBox1.Text &= "You Say: " & " " & TextBox2.Text & vbNewLine 'add a message to the chat textbox showing we have sent a public message
    End Sub
    Sub senddata(ByVal message As String) 'this sends a message to all connected clients
        Dim entry As DictionaryEntry 'declare a variable of type dictionary entry
        Try
            For Each entry In clients 'for each dictionary entry in the hashtable with all clients (clients)
                Dim cli As ConnectedClient = CType(entry.Key, ConnectedClient) ' cast the hashtable entry to a connection class
                cli.senddata(message) 'send the message to it
            Next  'go to the next client
        Catch
        End Try

    End Sub

End Class
0
Utilisateur anonyme
16 mars 2013 à 13:08
As-tu démarré ton serveur en premier ? As-tu autorisé les connexions sur le port 8888 ?
0
oui je fais tous
0
Rejoignez-nous