Question Simple Client and Server message help

paintballer4lfe

New member
Joined
Nov 7, 2011
Messages
1
Programming Experience
3-5
Alright i found a code on this forum for a simple TCP client and server that im trying to edit and change up to use when i get home from my training on some of the servers at my house.
Im setting up the server to send messages the all the clients(couldnt get specific clients to work), if the message contains cmd then the client server will open up a command prompt.

I can code the messages from the server to the client and how the client should handle it but i cant seem to get the client to send a message to the server and have the server display it.
what im trying to do broken down:
message from client>server recieves>displays message sent from client>done

heres what i have coding wise(im posting the whole thing because this is my first TCP/Networking VB program im messing with.

Client code so far:
VB.NET:
Imports System.Net.Sockets
Imports System.Net


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
        Dim UsrVar As String
        UsrVar = InputBox("Enter IP address of server", "Client End", , )
        client = New System.Net.Sockets.TcpClient(UsrVar, 991)
        client.GetStream.BeginRead(readBuffer, 0, BYTES_TO_READ, AddressOf doRead, Nothing)
        Dim h As System.Net.IPHostEntry = Net.Dns.GetHostByName(System.Net.Dns.GetHostName)
        lclIpLbl.Text = "Local IP: " + h.AddressList.GetValue(0).ToString
        AvalTmr.Enabled = True
    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)
        CnnSts.Text = "Connected"
        If message = "cmd" Then
            Process.Start("cmd.exe")
        Else
            MessageBox.Show(message)
        End If
    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


    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)


    End Sub


    Private Sub AvalTmr_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AvalTmr.Tick
        Label2.Text = "Available: " & client.Connected
        If Label2.Text = "Available: False" Then
            CnnSts.Text = "Disconnected!"
            ShutTmr.Enabled = True
        End If
    End Sub


    Private Sub ShutTmr_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ShutTmr.Tick
        End
    End Sub


    Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        SendMessage("test")
    End Sub


End Class

Server coding:
VB.NET:
'Server form1 code



Imports System.Net.Sockets
Imports System.Net
Imports System.Net.SocketAddress




Public Class Form1


    Private listener As System.Net.Sockets.TcpListener
    Private listenThread As System.Threading.Thread
    Private mcolClients As New Hashtable()


    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, 991) '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
            mcolClients.Add(connClient, connClient)
            Label1.Text = incomingClient.Client.RemoteEndPoint.ToString
            ClntLst.Items.Add(connClient)
            clients.Add(connClient) 'Adds the connected client to the list of connected clients.
            GetClientByName("test")






            For Each cc As ConnectedClient In clients
                cc.SendMessage("New client to the server...")
                ConnectedClient.ClntDsc.ToString()
            Next








        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


    Private Sub CntStsTmr_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CntStsTmr.Tick
        CntSts.Text = "Connected Clients: " & clients.Count
    End Sub


    Private Sub btnClntChg_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClntChg.Click
        Dim az As Integer = ClntLst.Items.IndexOf(ClntLst.SelectedItem)
        Dim strinput As String
        Dim Item As Object = ClntLst.Items.Item(az)
        Dim index As Integer = ClntLst.Items.IndexOf(Item)
        strinput = Label1.Text
        strinput.Replace(":", "")
        ClntLst.Items.Remove(ClntLst.SelectedItem)
        ClntLst.Items.Insert(index, strinput)
        GetClientByName(Label1.Text)
    End Sub


    Private Sub BtnRmvClnt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnRmvClnt.Click
        For Each cc As ConnectedClient In clients
            cc.SendMessage("cmd")
        Next
    End Sub




    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click


    End Sub


    Private Sub RcvMsgTmr_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RcvMsgTmr.Tick


    End Sub
End Class
ConnectedClient Class:
VB.NET:
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 Const ClntDsc As String = "test"


    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
            Form1.Label2.Text = mUsername
        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 Connection class(not being used):
VB.NET:
Imports System.Net.SocketsImports System.Reflection


Public NotInheritable Class ClientConnection
    Implements IDisposable
    Private Client As TcpClient
    Private PublicIP As String


    ' TODO: Add code for PublicIPAddress property here




    Public Sub New(ByVal client As TcpClient)
        ' Validate parameters


        If client Is Nothing Then
            Throw New ArgumentNullException("client")
        End If
        Me.Client = client
    End Sub


#Region " IDisposable Support "
    Private disposedValue As Boolean ' To detect redundant calls


    Private Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                ' TODO: free unmanaged resources here


                If Not Client Is Nothing Then
                    Client.Close()
                    Client = Nothing
                End If
            End If
            ' TODO: free shared unmanaged resources      


        End If
        Me.disposedValue = True
    End Sub


    Public Sub Dispose() Implements IDisposable.Dispose
        ' Do not change this code. Put cleanup code 


        ' in Dispose(ByVal disposing As Boolean) above.


        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region
    Public ReadOnly Property PublicIPAddress() As String
        Get
            If PublicIP = String.Empty Then
                Try
                    ' Get the clients IP address using Client property            


                    Dim ipend As Net.IPEndPoint = Client.Client.RemoteEndPoint
                    If Not ipend Is Nothing Then
                        PublicIP = ipend.Address.ToString
                    End If
                Catch ex As System.ObjectDisposedException
                    PublicIP = String.Empty
                Catch ex As SocketException
                    PublicIP = String.Empty
                End Try
            End If
            Return PublicIP
        End Get
    End Property


End Class
 
Back
Top