Hello dear memebers,
after searching for a multiple chat client i have come across a multithreading chat system which i have attached the code .I have taken the code of the server class and added it to my application form as well as the gui.My question is(well i know it will be sth easy in the end!) what i have done wrong and the server cannot send the message to the client.I do not get any errors,but the server starts and when sending the message it doesnt display it on the client screen.
If i run the server and the client from their original file and not from my application in which i have embedded them they run withount problems.It happens only if i run the server from ,my form and the client from the original file.
Imports System.IO
Imports System.Net.Sockets
Public Class ConnectedClient
Private cli As TcpClient 'decleare a tcp client which will be the client that we assign to an instance of this class
Private uniqueid As String 'this will be used for the name property
Public Property name ''This will be the name of the ID containing its Unique ID
Get
Return uniqueid 'when we want to get it, it will return the Unique ID
End Get
Set(ByVal value)
uniqueid = value 'Used for setting the name
End Set
End Property
Sub New(ByVal client As TcpClient)
Dim r As New Random 'create a new random to serve as way to create our unique ID
Dim x As String = String.Empty 'declare a new variable to hold the ID
For i = 0 To 7 'we are goign to have an ID of 7 randomly generated characters
x &= Chr(r.Next(65, 89)) 'create a generate dnumber between 65 and 89 and get the letter that has the same ascii value (A-Z)
' and add it onto the ID string
Next
Me.name = client.Client.RemoteEndPoint.ToString().Remove(client.Client.RemoteEndPoint.ToString().LastIndexOf(":")) & " - " & x 'set the name to the Unique ID
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
Public Event gotmessage(ByVal message As String, ByVal client As ConnectedClient) 'this is raised when we get a message from the client
Public Event disconnected(ByVal client As ConnectedClient) 'this is raised when we get the client disconnects
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
RaiseEvent disconnected(Me) 'WE CAN ASSUME THE CLIENT HAS DISCONNECTED
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
End Class
SERVER CLASS
Dim clients As New Hashtable 'new database (hashtable) to hold the clients
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
messageToDisplay.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
End Sub
Sub sendallbutone(ByVal message As String, ByVal exemptclientname As String) 'this sends to all clients except the one specified
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)
If entry.Value <> exemptclientname Then 'if the entry IS NOT the exempt client name
Dim cli As ConnectedClient = CType(entry.Key, ConnectedClient) ' cast the hashtable entry to a connection class
cli.senddata(message) 'send the message to it
End If
Next
Catch
End Try
End Sub
Sub sendsingle(ByVal message As String, ByVal clientname As String)
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)
If entry.Value = clientname Then 'if the entry is belongs to the client specified
Dim cli As ConnectedClient = CType(entry.Key, ConnectedClient) ' cast the hashtable entry to a connection class
cli.senddata(message) 'send the message to it
End If
Next
Catch
End Try
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
Sub disconnected(ByVal client As ConnectedClient) 'if a client is disconnected, this is raised
clients.Remove(client) 'remove the client from the hashtable
ListBox1.Items.Remove(client.name) 'remove it from our listbox
End Sub
Sub listen(ByVal port As Integer)
Try
Dim t As New TcpListener(IPAddress.Any, port) '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
Private Sub listen_port(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles listen_port_number.Click
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(portnumber.Text) 'start the listener, with the port specified as a parameter (textbox1 is our port textbox)
listen_port_number.Enabled = False 'disable our button so the user cannot try to make any further listeners which will result in errors
End Sub
Private Sub sendmessage_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles sendmessage_.Click
senddata("CHAT|" & messageToType.Text) 'send teh data with CHAT as the header so the clietn knows to process the message as a chat message
messageToDisplay.Text &= "You Say: " & " " & messageToType.Text & vbNewLine 'add a message to the chat textbox showing we have sent a public message
End Sub
Private Sub SendToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SendToolStripMenuItem.Click
Try
For Each cli As String In ListBox1.SelectedItems 'for each selected client in the selected listbox of our clients
sendsingle("CHAT|" & ToolStripTextBox1.Text, cli) 'send a message to the only the selected client by providing it's name as a second parameter
messageToDisplay.Text &= "To " & cli & " :" & " " & ToolStripTextBox1.Text.Split("|")(1) & vbNewLine 'add a message on textbox3 which suggests a private message
Next 'go to the next selected client if any
Catch
End Try
End Sub
CLIENT
Imports System.Net, System.Text
Imports System.Net.Sockets
Imports System.IO
Public Class Client
Dim t As New TcpClient
Sub connect(ByVal ip As String, ByVal port As Integer)
Try
t.Connect(ip, port) 'tries to connect
If t.Connected Then 'if connected, start the reading procedure
t.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf doread, Nothing)
login() 'send our details to the server
End If
Catch ex As Exception
System.Threading.Thread.Sleep(10000) 'if an error occurs sleep for 10 seconds
connect(ip, port) 'try to reconnect
End Try
End Sub
Sub login()
senddata("LOGIN|") 'log in to the chatserver
End Sub
Sub senddata(ByVal message As String)
Dim sw As New StreamWriter(t.GetStream) 'declare a new streamwriter
sw.WriteLine(message) 'write the message
sw.Flush()
End Sub
Sub messagerecieved(ByVal message As String)
Dim msg() As String = message.Split("|") ' if a message is recieved, split it to process it
Select Case msg(0) 'process it by the first element in the split array
Case "CHAT"
TextBox4.Text &= "Server: " & " " & msg(1) & vbNewLine
End Select
End Sub
Sub doread(ByVal ar As IAsyncResult)
Try
Dim sr As New StreamReader(t.GetStream) 'declare a new streamreader to read fromt eh network stream
Dim msg As String = sr.ReadLine() 'the msg is what is bing read
messagerecieved(msg) 'start processing the message
t.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf doread, Nothing) 'continue to read
Catch ex As Exception
System.Threading.Thread.Sleep(10000) 'if an error occurs, wait for 10 seconds
connect(TextBox1.Text, TextBox2.Text) 'try to reconnect
End Try
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
connect(TextBox1.Text, TextBox2.Text) 'connect textbox1 as ip and textbox2 as port
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
senddata("CHAT|" & TextBox3.Text) 'send the data with CHAT| as header
TextBox4.Text &= "You: " & " " & TextBox3.Text.Split("|")(0) & vbNewLine
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
End Class
I have checked if there is anything wrog with the ports or the ip but it only listen to one port and i use it through my network card 127.0.0.1.
Thank you all in advance.