Const PORT_NUM As Integer = 29016
Private clients As New Hashtable()
Private listener As TcpListener
Private listenerThread As Threading.Thread
' This subroutine sends a message to all attached clients
Public Sub Broadcast(ByVal strMessage As String)
Dim client As UserConnection
Dim entry As DictionaryEntry
' All entries in the clients Hashtable are UserConnection so it is possible
' to assign it safely.
For Each entry In clients
client = CType(entry.Value, UserConnection)
client.SendData(strMessage)
Next
End Sub
Public Sub ConnectUser(ByVal userName As String, ByVal sender As UserConnection)
If clients.Contains(userName) Then
ReplyToSender("REFUSE", sender)
Else
sender.Name = userName
UpdateStatus(userName & " has joined the chat.")
clients.Add(userName, sender)
ListBox2.Items.Add(userName)
' Send a JOIN to sender, and notify all other clients that sender joined
ReplyToSender("JOIN", sender)
SendToClients("CHAT|" & sender.Name & " has joined the chat.", sender)
End If
End Sub
Public Sub DisconnectUser(ByVal sender As UserConnection)
UpdateStatus(sender.Name & " has left the chat.")
SendToClients("CHAT|" & sender.Name & " has left the chat.", sender)
clients.Remove(sender.Name)
End Sub
Public Sub DoListen()
Try
' Listen for new connections.
listener = New TcpListener(System.Net.IPAddress.Any, PORT_NUM)
listener.Start()
Do
' Create a new user connection using TcpClient returned by
' TcpListener.AcceptTcpClient()
Dim client As New UserConnection(listener.AcceptTcpClient)
' Create an event handler to allow the UserConnection to communicate
' with the window.
AddHandler client.LineReceived, AddressOf OnLineReceived
UpdateStatus("New connection found: waiting for log-in")
Loop Until False
Catch
End Try
End Sub
Public Sub ListUsers(ByVal sender As UserConnection)
Dim client As UserConnection
Dim entry As DictionaryEntry
Dim strUserList As String
UpdateStatus("Sending " & sender.Name & " a list of users online.")
strUserList = "LISTUSERS"
' All entries in the clients Hashtable are UserConnection so it is possible
' to assign it safely.
For Each entry In clients
client = CType(entry.Value, UserConnection)
strUserList = strUserList & "|" & client.Name
Next
' Send the list to the sender.
ReplyToSender(strUserList, sender)
End Sub
Public Sub OnLineReceived(ByVal sender As UserConnection, ByVal data As String)
Dim dataArray() As String
' Message parts are divided by "|" Break the string into an array accordingly.
dataArray = data.Split(Chr(124))
' dataArray(0) is the command.
Select Case dataArray(0)
Case "CONNECT"
ConnectUser(dataArray(1), sender)
Case "CHAT"
SendChat(dataArray(1), sender)
Case "DISCONNECT"
DisconnectUser(sender)
Case "REQUESTUSERS"
ListUsers(sender)
Case Else
UpdateStatus("Unknown message:" & data)
End Select
End Sub
Public Sub ReplyToSender(ByVal strMessage As String, ByVal sender As UserConnection)
sender.SendData(strMessage)
End Sub
' Send a chat message to all clients except sender.
Public Sub SendChat(ByVal message As String, ByVal sender As UserConnection)
UpdateStatus(sender.Name & ": " & message)
SendToClients("CHAT|" & sender.Name & ": " & message, sender)
End Sub
' This subroutine sends a message to all attached clients except the sender.
Public Sub SendToClients(ByVal strMessage As String, ByVal sender As UserConnection)
Dim client As UserConnection
Dim entry As DictionaryEntry
' All entries in the clients Hashtable are UserConnection so it is possible
' to assign it safely.
For Each entry In clients
client = CType(entry.Value, UserConnection)
' Exclude the sender.
If client.Name <> sender.Name Then
client.SendData(strMessage)
End If
Next
End Sub
' This subroutine adds line to the Status listbox
Public Sub UpdateStatus(ByVal statusMessage As String)
ListBox1.Items.Add(statusMessage)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
listenerThread = New Threading.Thread(AddressOf DoListen)
listenerThread.Start()
UpdateStatus("Listener started")
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If TextBox2.Text <> "" Then
UpdateStatus("Broadcasting: " & TextBox2.Text)
Broadcast("BROAD|" & TextBox2.Text)
TextBox2.Text = ""
End If
End Sub