Please help solve this problem
Please help solve this problem
Please help solve this problem
Please help solve this problem
Please help solve this problem
Please help solve this problem Please help solve this problem Please help solve this problem Please help solve this problem Please help solve this problem Please help solve this problem Please help solve this problem Please help solve this problem
Please help solve this problem Please help solve this problem
Please help solve this problem
Go Back  Xtreme Visual Basic Talk > > > Please help solve this problem


Reply
 
Thread Tools Display Modes
  #1  
Old 09-20-2011, 10:47 PM
godlydanny godlydanny is offline
Newcomer
 
Join Date: Jul 2011
Posts: 3
Default Please help solve this problem


Hello and thank you for taking your time reading this post,
Please help me resolve why Workstation (FORM Form1) cant use "me.close()" or SUB or Function c in Public Sub messageReceived

GENERAL INFORMATION:

Admin Panel (FORM Main) Sends TCP Packets to Workstation (FORM Form1) it then gets HANDLED by Workstation (CLASS ConnectedClient) than it EVENT HANDLE back to Workstation (FORM Form1). I tested the string , and I successfully received the string, BUT it seems only thing i can trigger is MSGBOX() and Debug.Print() at Workstation (FORM Form1 Public Sub messageRecieved)

EXAMPLE: I tried putting me.close() inside Public Sub messageRecieved and got this error:
A first chance exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
A first chance exception of type 'System.NullReferenceException' occurred in

Thank you for your time and attention,
Sincerely,
Danny


Workstation (FORM Form1)
Code:
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
'The TcpListener will listen for incoming connections at port 43001
        listener = New System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, 43001) 
'Start listening.
        listener.Start() 
'This thread will run the doListen method
        listenThread = New System.Threading.Thread(AddressOf doListen) 
'Since we dont want this thread to keep on running after the application closes, we set isBackground to true.
        listenThread.IsBackground = True 
'Start executing doListen on the worker thread.
        listenThread.Start() 
    End Sub

    Private Sub doListen()
        Dim incomingClient As System.Net.Sockets.TcpClient
        Do
'Accept the incoming connection. This is a blocking method so execution will halt here until someone tries to connect.
            incomingClient = listener.AcceptTcpClient 
'Create a new instance of ConnectedClient (check its constructor to see whats happening now).
            Dim connClient As New ConnectedClient(incomingClient, Me) 
            AddHandler connClient.dataReceived, AddressOf Me.messageReceived
'Adds the connected client to the list of connected clients.
            clients.Add(connClient) 

        Loop
    End Sub

    Public Sub removeClient(ByVal client As ConnectedClient)
        If clients.Contains(client) Then
            clients.Remove(client)
        End If
    End Sub

    Public Sub messageReceived(ByVal sender As ConnectedClient, ByVal message As String)
        Dim opt() As String
        opt = Split(message, ":")

        Select Case opt(0)
            Case "End"
                EndNow()
        End Select

        MsgBox(message)

    End Sub

    Public Sub EndNow()
        Try

            Me.Close()

        Catch ex As Exception
            Debug.Print(ex.InnerException.ToString)
            Debug.Print(ex.Message)

        End Try
    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
Workstation (CLASS ConnectedClient)
Code:
Public Class ConnectedClient

#Region "TCPSocketSettings"
    Private mClient As System.Net.Sockets.TcpClient
    Private mUsername As String
    Private mParentForm As Main
    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)
#End Region

    Sub New(ByVal client As System.Net.Sockets.TcpClient, ByVal parentForm As Main)
        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
        Try
            Do
                bytesRead = mClient.GetStream.Read(readBuffer, 0, BYTES_TO_READ)
                sBuilder.Clear()
                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

                RecievedMessage(sBuilder.ToString)
            Loop

        Catch ex As Exception
        End Try
    End Sub

    Public Sub SendMessage(ByVal msg As String)
        Dim sw As IO.StreamWriter
        Try
            SyncLock mClient.GetStream
                'Create a new streamwriter that will be writing directly to the networkstream.
                sw = New IO.StreamWriter(mClient.GetStream) 
                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

    Private Sub RecievedMessage(ByVal msg As String)
        RaiseEvent dataReceived(Me, msg)

        
    End Sub
End Class
Admin Panel (FORM Main)
Code:
Public Class Main
#Region "SettingsForTCPSocket"
    Private client As System.Net.Sockets.TcpClient
    Private Const BYTES_TO_READ As Integer = 255
    Private readBuffer(BYTES_TO_READ) As Byte
#End Region

    Private Sub ConnectToWorkstation(ByVal IP)
        client = New System.Net.Sockets.TcpClient(IP, 43001)
        client.GetStream.BeginRead(readBuffer, 0, BYTES_TO_READ, AddressOf doRead, Nothing)
    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
            MsgBox("Fail to connect to workstation")
        End Try
    End Sub
    Private Sub doRead(ByVal ar As System.IAsyncResult)
        Dim recievedstring As String = ""
        Dim totalRead As Integer
        totalRead = client.GetStream.EndRead(ar) 'Ends the reading and returns the number of bytes read.
        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




    Public Sub ConnectPacketTest(ByVal IP)
        ConnectToWorkstation(IP)
   SendMessage("Guest:123456")
    End Sub



End Class

Last edited by Flyguy; 09-21-2011 at 02:39 AM. Reason: Moved comments for better screen layout
Reply With Quote
  #2  
Old 09-21-2011, 03:01 AM
DrPunk's Avatar
DrPunkPlease help solve this problem DrPunk is offline
Senior Contributor

* Expert *
 
Join Date: Apr 2003
Location: Never where I want to be
Posts: 1,403
Default

Looks like it's a cross threading issue.

MSDN can probably explain better than me -> http://msdn.microsoft.com/en-us/library/ms171728.aspx
__________________
There are no computers in heaven!
Reply With Quote
  #3  
Old 09-21-2011, 07:33 AM
godlydanny godlydanny is offline
Newcomer
 
Join Date: Jul 2011
Posts: 3
Default

Hi DrPunk,

Private Sub messageReceived(ByVal sender As ConnectedClient, ByVal message As String)
Control.CheckForIllegalCrossThreadCalls = False
End sub

I tried that and it seems like it kinda work, but nothing showing still.
any solutions?

Thanks
Reply With Quote
  #4  
Old 09-21-2011, 08:14 AM
DrPunk's Avatar
DrPunkPlease help solve this problem DrPunk is offline
Senior Contributor

* Expert *
 
Join Date: Apr 2003
Location: Never where I want to be
Posts: 1,403
Default

The problem is that you can only call the Form.Close on the form's thread, not the new thread that you've created that's trying to call it.

Now, I don't claim to understand it all properly and I doubt my solution is the most attractive way of doing it (it's out of an oldish book and things are bound to have changed since then) but the way that I'd solve the problem is creating two variables to use (with form scope)...
Code:
Private delegate EndNowDelegate
Private EndNowMarshaler As EndNowDelegate = AddressOf EndNow
And then when you want to call the EndNow routine on the form's thread you use BeginInvoke on the Marshaler.
Code:
Public Sub messageReceived(ByVal sender As ConnectedClient, ByVal message As String)
    Dim opt() As String
    opt = Split(message, ":")

    Select Case opt(0)
        Case "End"
            mybase.begininvoke(EndNowMarshaler)
    End Select

    MsgBox(message)

End Sub
That will get it to call EndNow on the form's thread and allow Me.Close to be called.
__________________
There are no computers in heaven!
Reply With Quote
  #5  
Old 09-21-2011, 10:07 AM
godlydanny godlydanny is offline
Newcomer
 
Join Date: Jul 2011
Posts: 3
Default

I want to say DrPunk is A HERO OF GodlyDanny =)
Thanks , thread resolved. any moderator can mark this as resolved so other people who have same problem can use this as a TIP.

Thank you DrPunk once agian.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Please help solve this problem
Please help solve this problem
Please help solve this problem Please help solve this problem
Please help solve this problem
Please help solve this problem
Please help solve this problem Please help solve this problem Please help solve this problem Please help solve this problem Please help solve this problem Please help solve this problem Please help solve this problem
Please help solve this problem
Please help solve this problem
 
Please help solve this problem
Please help solve this problem
 
-->