Revision: 12663
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at March 24, 2009 10:51 by mcgraf
Initial Code
'server side Public Class Form1 Private listener As System.Net.Sockets.TcpListener Private listenThread As System.Threading.Thread Private clients As New List(Of ConnectedClient) 'This list will store all connected clients. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load listener = New System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, 43001) 'The TcpListener will listen for incoming connections at port 43001 listener.Start() 'Start listening. listenThread = New System.Threading.Thread(AddressOf doListen) 'This thread will run the doListen method listenThread.IsBackground = True 'Since we dont want this thread to keep on running after the application closes, we set isBackground to true. listenThread.Start() 'Start executing doListen on the worker thread. End Sub Private Sub doListen() Dim incomingClient As System.Net.Sockets.TcpClient Do incomingClient = listener.AcceptTcpClient 'Accept the incoming connection. This is a blocking method so execution will halt here until someone tries to connect. Dim connClient As New ConnectedClient(incomingClient, Me) 'Create a new instance of ConnectedClient (check its constructor to see whats happening now). AddHandler connClient.dataReceived, AddressOf Me.messageReceived clients.Add(connClient) 'Adds the connected client to the list of connected clients. Loop End Sub Public Sub removeClient(ByVal client As ConnectedClient) If clients.Contains(client) Then clients.Remove(client) End If End Sub Private Sub messageReceived(ByVal sender As ConnectedClient, ByVal message As String) 'A message has been received from one of the clients. 'To determine who its from, use the sender object. 'sender.SendMessage can be used to reply to the sender. Dim data() As String = message.Split("|"c) 'Split the message on each | and place in the string array. Select Case data(0) Case "CONNECT" 'We use GetClientByName to make sure no one else is using this username. 'It will return Nothing if the username is free. 'Since the client sent the message in this format: CONNECT|UserName, the username will be in the array on index 1. If GetClientByName(data(1)) Is Nothing Then 'The username is not taken, we can safely assign it to the sender. sender.Username = data(1) End If Case "DISCONNECT" removeClient(sender) End Select End Sub Private Function GetClientByName(ByVal name As String) As ConnectedClient For Each cc As ConnectedClient In clients If cc.Username = name Then Return cc 'client found, return it. End If Next 'If we've reached this part of the method, there is no client by that name Return Nothing End Function End Class 'client side Public Class ConnectedClient Private mClient As System.Net.Sockets.TcpClient Private mUsername As String Private mParentForm As Form1 Private readThread As System.Threading.Thread Private Const MESSAGE_DELIMITER As Char = ControlChars.Cr Public Event dataReceived(ByVal sender As ConnectedClient, ByVal message As String) Sub New(ByVal client As System.Net.Sockets.TcpClient, ByVal parentForm As Form1) mParentForm = parentForm mClient = client readThread = New System.Threading.Thread(AddressOf doRead) readThread.IsBackground = True readThread.Start() End Sub Public Property Username() As String Get Return mUsername End Get Set(ByVal value As String) mUsername = value End Set End Property Private Sub doRead() Const BYTES_TO_READ As Integer = 255 Dim readBuffer(BYTES_TO_READ) As Byte Dim bytesRead As Integer Dim sBuilder As New System.Text.StringBuilder Do bytesRead = mClient.GetStream.Read(readBuffer, 0, BYTES_TO_READ) If (bytesRead > 0) Then Dim message As String = System.Text.Encoding.UTF8.GetString(readBuffer, 0, bytesRead) If (message.IndexOf(MESSAGE_DELIMITER) > -1) Then Dim subMessages() As String = message.Split(MESSAGE_DELIMITER) 'The first element in the subMessages string array must be the last part of the current message. 'So we append it to the StringBuilder and raise the dataReceived event sBuilder.Append(subMessages(0)) RaiseEvent dataReceived(Me, sBuilder.ToString) sBuilder = New System.Text.StringBuilder 'If there are only 2 elements in the array, we know that the second one is an incomplete message, 'though if there are more then two then every element inbetween the first and the last are complete messages: If subMessages.Length = 2 Then sBuilder.Append(subMessages(1)) Else For i As Integer = 1 To subMessages.GetUpperBound(0) - 1 RaiseEvent dataReceived(Me, subMessages(i)) Next sBuilder.Append(subMessages(subMessages.GetUpperBound(0))) End If Else 'MESSAGE_DELIMITER was not found in the message, so we just append everything to the stringbuilder. sBuilder.Append(message) End If End If Loop End Sub Public Sub SendMessage(ByVal msg As String) Dim sw As IO.StreamWriter Try SyncLock mClient.GetStream sw = New IO.StreamWriter(mClient.GetStream) 'Create a new streamwriter that will be writing directly to the networkstream. sw.Write(msg) sw.Flush() End SyncLock Catch ex As Exception MessageBox.Show(ex.ToString) End Try 'As opposed to writing to a file, we DONT call close on the streamwriter, since we dont want to close the stream. End Sub End Class 'client side form Public Class Form1 Private client As System.Net.Sockets.TcpClient Private Const BYTES_TO_READ As Integer = 255 Private readBuffer(BYTES_TO_READ) As Byte Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load client = New System.Net.Sockets.TcpClient("localhost", 43001) client.GetStream.BeginRead(readBuffer, 0, BYTES_TO_READ, AddressOf doRead, Nothing) End Sub Private Sub doRead(ByVal ar As System.IAsyncResult) Dim totalRead As Integer Try totalRead = client.GetStream.EndRead(ar) 'Ends the reading and returns the number of bytes read. Catch ex As Exception 'The underlying socket have probably been closed OR an error has occured whilst trying to access it, either way, this is where you should remove close all eventuall connections 'to this client and remove it from the list of connected clients. End Try If totalRead > 0 Then 'the readBuffer array will contain everything read from the client. Dim receivedString As String = System.Text.Encoding.UTF8.GetString(readBuffer, 0, totalRead) messageReceived(receivedString) End If Try client.GetStream.BeginRead(readBuffer, 0, BYTES_TO_READ, AddressOf doRead, Nothing) 'Begin the reading again. Catch ex As Exception 'The underlying socket have probably been closed OR an error has occured whilst trying to access it, either way, this is where you should remove close all eventuall connections 'to this client and remove it from the list of connected clients. End Try End Sub Private Sub messageReceived(ByVal message As String) MessageBox.Show(message) End Sub Private Sub SendMessage(ByVal msg As String) Dim sw As IO.StreamWriter Try sw = New IO.StreamWriter(client.GetStream) sw.Write(msg) sw.Flush() Catch ex As Exception MessageBox.Show(ex.ToString) End Try End Sub End Class
Initial URL
Initial Description
Initial Title
TCP socket server example 2
Initial Tags
Initial Language
VB.NET