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
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
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