Multi Client Socket / Chat Room
I'm trying to understand and work through multiple TCP clients using Visual Basic.
The below code uses a Module for the Server:
Code:
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Module Module1
Dim clientsList As New Hashtable
Sub Main()
'SETUP SERVER CONNECTION IP / PORT
Dim Port As Int32 = 8888
Dim Address As IPAddress = IPAddress.Parse("127.0.0.1")
Dim ServerSocket As New TcpListener(Address, Port)
Dim clientSocket As TcpClient = Nothing
Dim infiniteCounter As Integer
Dim counter As Integer
ServerSocket.Start()
msg("Chat Server Started ....")
counter = 0
infiniteCounter = 0
For infiniteCounter = 1 To 2
infiniteCounter = 1
counter += 1
clientSocket = ServerSocket.AcceptTcpClient()
Dim bytesFrom(10024) As Byte
Dim dataFromClient As String
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("$"))
clientsList(dataFromClient) = clientSocket
'CLIENT SIDE MESSAGE (SEEN ON CLIENT)
broadcast(dataFromClient + " Joined ", dataFromClient, False)
'SERVER SIDE MESSAGE (SEEN ON SERVER / CMD)
msg(dataFromClient + " Joined chat room ")
Dim client As New handleClinet
client.startClient(clientSocket, dataFromClient, clientsList)
Next
clientSocket.Close()
ServerSocket.Stop()
msg("exit")
Console.ReadLine()
End Sub
Sub msg(ByVal mesg As String)
mesg.Trim()
Console.WriteLine(" >> " + mesg)
End Sub
Private Sub broadcast(ByVal msg As String, ByVal uName As String, ByVal flag As Boolean)
For Each Item In clientsList
Dim broadcastSocket As TcpClient
broadcastSocket = CType(Item.Value, TcpClient)
Dim broadcastStream As NetworkStream = broadcastSocket.GetStream()
Dim broadcastBytes As [Byte]()
If flag = True Then
broadcastBytes = Encoding.ASCII.GetBytes(uName + " says : " + msg)
Else
broadcastBytes = Encoding.ASCII.GetBytes(msg)
End If
broadcastStream.Write(broadcastBytes, 0, broadcastBytes.Length)
broadcastStream.Flush()
Next
End Sub
Public Class handleClinet
Dim clientSocket As TcpClient
Dim clNo As String
Dim clientsList As Hashtable
Public Sub startClient(ByVal inClientSocket As TcpClient, ByVal clineNo As String, ByVal cList As Hashtable)
Me.clientSocket = inClientSocket
Me.clNo = clineNo
Me.clientsList = cList
Dim ctThread As Threading.Thread = New Threading.Thread(AddressOf doChat)
ctThread.Start()
End Sub
Private Sub doChat()
Dim infiniteCounter As Integer
Dim requestCount As Integer
Dim bytesFrom(10024) As Byte
Dim dataFromClient As String
Dim sendBytes As [Byte]()
Dim serverResponse As String
Dim rCount As String
Try
requestCount = 0
For infiniteCounter = 1 To 2
infiniteCounter = 1
requestCount = requestCount + 1
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("$"))
msg("From client - " + clNo + " : " + dataFromClient)
rCount = Convert.ToString(requestCount)
broadcast(dataFromClient, clNo, True)
Next
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
End Class
End Module
And this code uses Windows Forms for the Client >
Code:
Imports System.Net.Sockets
Imports System.Text
Public Class Form1
Dim clientSocket As New System.Net.Sockets.TcpClient()
Dim serverStream As NetworkStream
Dim readData As String
Dim infiniteCounter As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim outStream As Byte() = System.Text.Encoding.ASCII.GetBytes(TextBox2.Text + "$")
serverStream.Write(outStream, 0, outStream.Length)
serverStream.Flush()
End Sub
Private Sub msg()
If Me.InvokeRequired Then
Me.Invoke(New MethodInvoker(AddressOf msg))
Else
'If readData.Contains(" Joined") Then
'ListBox1.Items.Add(readData.Replace(" Joined", ""))
'End If
TextBox1.Text = TextBox1.Text + Environment.NewLine + " >> " + readData
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
readData = "Connected to Chat Server ..."
msg()
clientSocket.Connect("127.0.0.1", 8888)
serverStream = clientSocket.GetStream()
'NICKNAME
Dim outStream As Byte() = System.Text.Encoding.ASCII.GetBytes(TextBox3.Text + "$")
serverStream.Write(outStream, 0, outStream.Length)
serverStream.Flush()
Dim ctThread As Threading.Thread = New Threading.Thread(AddressOf getMessage)
ctThread.Start()
End Sub
Private Sub getMessage()
For Me.infiniteCounter = 1 To 2
infiniteCounter = 1
serverStream = clientSocket.GetStream()
Dim buffSize As Integer
Dim inStream(10024) As Byte
buffSize = clientSocket.ReceiveBufferSize
serverStream.Read(inStream, 0, buffSize)
Dim returndata As String = System.Text.Encoding.ASCII.GetString(inStream)
readData = "" + returndata
msg()
Next
End Sub
End Class
These codes work perfectly, as intended; to my knowledge. The question is how to add the ClientList
to a listbox. The purpose of the listbox is to show the currently active connections as clients, just like
a chat room. Using the commented code >
Code:
'If readData.Contains(" Joined") Then
'ListBox1.Items.Add(readData.Replace(" Joined", ""))
'End If
TextBox1.Text = TextBox1.Text + Environment.NewLine + " >> " + readData
I was able to add the Clients to the listbox as they joined, however this was far from what I wanted
to achieve. How can I go about doing this?
Thank You!
Re: Multi Client Socket / Chat Room
If you have a list of objects then you can bind it to a ListBox. Assign the list to the DataSource property of the ListBox and you will see the result of the ToString method displayed. If you want the value of a particular property displayed then you can assign the name of the property to the DisplayMember.
If your list might change and you want that change reflected in the ListBox then bind the list to a BindingSource and bind that to the ListBox. The BindingSource has methods to update the control to reflect changes in the list, so you can call the appropriate one each time you make a change. Check out the MSDN documentation for the class to find out what those methods are.
Re: Multi Client Socket / Chat Room
Thank You for your response!
I found that adding this code >
Code:
For Each I As System.Collections.DictionaryEntry In ClientList
Console.WriteLine(I.Key.ToString)
Next
Will show the currently active TCP connections names. ^_^