Unknown problem

Hello! I am writing application which is server which communicates with client by socket. The server contains one form "frmMain" and one module "Module1". Module1 contains the following lines:

Imports System

Imports System.IO

Imports System.Net

Imports System.Net.Sockets

Module Module1

Public Const BS_PORT = 8221

Private pfnWorkerCallBack As AsyncCallback

Private soclistener As Socket

Private socWorker As Socket

Public Sub StartListening(ByVal Port As Integer)

Try

Dim ipLocal As IPEndPoint = New IPEndPoint(IPAddress.Any, Port)

soclistener = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

soclistener.Bind(ipLocal)

soclistener.Listen(4)

soclistener.BeginAccept(New AsyncCallback(AddressOf OnClientConnect), Nothing)

Catch ex As Exception

End Try

End Sub

Private Sub OnClientConnect(ByVal asyn As IAsyncResult)

frmMain.rtbMessages.Text= “Client connected”

Try

socWorker = soclistener.EndAccept(asyn)

WaitForData(socWorker)

Catch ex As Exception

End Try

End Sub

Private Sub WaitForData(ByVal soc As Socket)

Try

Dim theSocPkt As CSocketPacket = New CSocketPacket()

If pfnWorkerCallBack Is Nothing Then

pfnWorkerCallBack = New AsyncCallback(AddressOf OnDataReceived)

End If

theSocPkt.thisSocket = soc

' now start to listen for any data...

soc.BeginReceive(theSocPkt.dataBuffer, 0, theSocPkt.dataBuffer.Length, SocketFlags.None, _

pfnWorkerCallBack, theSocPkt)

Catch ex As Exception

End Try

End Sub

Private Sub OnDataReceived(ByVal asyn As IAsyncResult)

Try

Dim theSockId As CSocketPacket = CType(asyn.AsyncState, CSocketPacket)

'end receive...

Dim iRx As Integer = 0

iRx = theSockId.thisSocket.EndReceive(asyn)

Dim chars As Char() = New Char(iRx) {}

Dim d As System.Text.Decoder = System.Text.Encoding.UTF8.GetDecoder()

Dim charLen As Integer = d.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0)

Dim szData As System.String = New System.String(chars)

'szData is the received data

rtbMessages.Text &= szData

WaitForData(socWorker)

Catch ex As Exception

End Try

End Sub

Private Class CSocketPacket

Public thisSocket As Socket

Public dataBuffer As Byte() = New Byte(0) {}

End Class

End Module

StartListening is called in frmMain_Shown. When I run this project and the client is connected to the application, the text in rtbMessages (RichTextBox in frmMain) is not changed. Where is the problem… I think that the problem Is with the threads but I don’t know how to solve it.

Thanks!



Answer this question

Unknown problem

  • Womble--

    No. This is occuring in UpdateDisplayInMainFormsThread in line: Me.Invoke(...)


  • anandcbe14

    No. Invoke is not required.
  • Junmei

    I have run into a simular problem when using Delegates. The issue is because the method:

    Private Sub OnDataReceived(ByVal asyn As IAsyncResult) is actually run in a different thread than the Form and RichTextBox are running.


    You can solve this by creatng a delegate sub on the main form, it would look something like this:



    '-----------------------------------------------------------------------------------------------

    ' Add to your form.


    ' Declare the Delegate.

    private UpdateDisplayDelegate(ByVal message As String)


    ' Declare the method to handle the Delegate.

    private Sub UpdateDisplay(ByVal message As String)

    rtbMessages.SelectedText = message

    rtbMessages.Refresh()

    End Sub


    ' The public method called by Module1

    public Sub UpdateDisplayInMainFormsThread(ByVal message as String)

    Dim upd As New UpdateDisplayDelegate(AddressOf UpdateDisplay)

    Me.Invoke(atd, New Object() {message})


    'Me.Invoke causes the Delegate sub to be run

    'in the Main Form's thread.

    End Sub



    '-----------------------------------------------------------------------------------------------

    ' Change in Module1


    ' All references to frmMain.rtbMessages.Text should be changed to...


    frmMain.UpdateDisplayInMainFormsThread("Your message goes here.")


  • JavaBoy

    Do you have this occuring durring form load routine

  • etude

    I've made this changes and the following exception is thrown: "ex = {"Invoke or BeginInvoke cannot be called on a control until the window handle has been created."}". I tryied with Me.CreateHandle before Me.Invoke but the text in rtbMessages wasn't chaged...
  • mta37

    Can you post the updated version of your code so we can take a look at it

  • AboOmar

    Right I know the error occurs in the Me.Invoke method. But what I was asking was when is the listener started. After reading your question over again I realized it is started in the frmMain_Shown routine (frmMain_Load). The controls window handles are not created at that point. You can solve this a couple of ways.

    1. Put a button on your form [Start Listening] or something like that. Then move your code into the Button_OnClick method.

    2. Put a 2 second timer that only runs once on your form that is started in your frmMain_Load method. Move your code into the Timer_Tick method.

  • MaryMary

    Before invoking, try checking if Invoke is required (e.g. me.invokeRequired).



  • jiveshc

    I've tried with Timer and it didn't worked again :(:(:(:(
  • xr280xr

    Then don't invoke ...set the properties directly.

    Usually, a routine which needs to do something like this (update user interface objects on a different thread) the following pattern could be used:

    delegate UpdateUICallback(<UI Parameters>)

    Sub UpdateUI(<UI Parameters>)
    if InvokeRequired then
    d as new UpdateUICallback( addressof UpdateUI)
    invoke(d, new object {<UI Parameters>})
    else
    <Use UI Parameters Directly>
    end if
    End sub



  • DHJr

    SJWhiteley wrote:

    Then don't invoke ...set the properties directly.

    Usually, a routine which needs to do something like this (update user interface objects on a different thread) the following pattern could be used:

    delegate UpdateUICallback(<UI Parameters>)

    Sub UpdateUI(<UI Parameters>)
    if InvokeRequired then
    d as new UpdateUICallback( addressof UpdateUI)
    invoke(d, new object {<UI Parameters>})
    else
    <Use UI Parameters Directly>
    end if
    End sub

    That was the first thing that I've tried but it doesn't works :(


  • Unknown problem