Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

asychronous tcl listener 1

Status
Not open for further replies.

sillysod

Technical User
Jan 6, 2004
300
GB
Hi i am trying to set up an app that runs as a server, accepted messages from a client pc

The server does recieve the messages and echoes the message back to the client as it should, however whilst the following code is running, the application gui freezes and wont allow me to do anything else, whereas i was under the impression the asychronous approach would cause the app to still function fully while this code ran in the background? Where am i going wrong?

Code:
' Thread signal.
    Public Shared allDone As New ManualResetEvent(False)

    ' This server waits for a connection and then uses  asychronous operations to
    ' accept the connection, get data from the connected client, 
    ' echo that data back to the connected client.
    ' It then disconnects from the client and waits for another client. 
    Public Shared Sub Main()
        Try

            clsServer.WriteToLog("Server Started ...")
            Control.CheckForIllegalCrossThreadCalls = False
            ' Data buffer for incoming data.
            Dim bytes() As Byte = New [Byte](1023) {}
            ' Establish the local endpoint for the socket.
            Dim ipHostInfo As IPHostEntry = Dns.GetHostEntry(Dns.GetHostName())
            Dim ipAddress As IPAddress = ipHostInfo.AddressList(0)
            Dim localEndPoint As New IPEndPoint(ipAddress, 11000)


            ' Create a TCP/IP socket.
            Dim listener As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

            ' Bind the socket to the local endpoint and listen for incoming connections.
            listener.Bind(localEndPoint)
            listener.Listen(100)

            While True
                ' Set the event to nonsignaled state.
                allDone.Reset()

                ' Start an asynchronous socket to listen for connections.

                listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), listener)

                ' Wait until a connection is made and processed before continuing.

                allDone.WaitOne()
            End While
        Catch e As Exception
            clsServer.WriteToLog(e.Message)
        End Try

    End Sub 'Main


    Public Shared Sub AcceptCallback(ByVal ar As IAsyncResult)
        ' Get the socket that handles the client request.
        Dim listener As Socket = CType(ar.AsyncState, Socket)
        ' End the operation.
        Dim handler As Socket = listener.EndAccept(ar)

        ' Create the state object for the async receive.
        Dim state As New StateObject
        state.workSocket = handler
        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)
    End Sub 'AcceptCallback


    Public Shared Sub ReadCallback(ByVal ar As IAsyncResult)
        Dim content As String = String.Empty

        ' Retrieve the state object and the handler socket
        ' from the asynchronous state object.
        Dim state As StateObject = CType(ar.AsyncState, StateObject)
        Dim handler As Socket = state.workSocket

        ' Read data from the client socket. 
        Dim bytesRead As Integer = handler.EndReceive(ar)

        If bytesRead > 0 Then
            ' There  might be more data, so store the data received so far.
            state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead))

            ' Check for end-of-file tag. If it is not there, read 
            ' more data.
            content = state.sb.ToString()
            If content.IndexOf("<EOF>") > -1 Then
                ' All the data has been read from the 
                ' client. Display it on the console.
                clsServer.WriteToLog("Read {0} bytes from socket. " + vbLf + " Data : " & content.Length & " " & content)
                ' Echo the data back to the client.
                Send(handler, content)
            Else
                ' Not all data received. Get more.
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)
            End If
        End If
    End Sub 'ReadCallback

    Private Shared Sub Send(ByVal handler As Socket, ByVal data As String)
        ' Convert the string data to byte data using ASCII encoding.
        Dim byteData As Byte() = Encoding.ASCII.GetBytes(data)

        ' Begin sending the data to the remote device.
        handler.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), handler)
    End Sub 'Send


    Private Shared Sub SendCallback(ByVal ar As IAsyncResult)
        ' Retrieve the socket from the state object.
        Dim handler As Socket = CType(ar.AsyncState, Socket)

        ' Complete sending the data to the remote device.
        Dim bytesSent As Integer = handler.EndSend(ar)
        clsServer.WriteToLog("Sent {0} bytes to client. " & bytesSent)

        handler.Shutdown(SocketShutdown.Both)
        handler.Close()
        ' Signal the main thread to continue.
        allDone.Set()
    End Sub 'SendCallback
 
That appears to be the thread class. How are you starting the new thread? Do you use the Thread class or a BackgroundWorker (preferred by Microsoft)?

____________________________________________________________________________
There are only 10 types of people in the world. Those that know binary and those that don't

Brent
 
the thread is started here

Code:
listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), listener)

the

Code:
Control.CheckForIllegalCrossThreadCalls = False

is a hack that will kill you in the end. There are severeal threads on the first page of this forum about crossthread handling so use that.

your proble starts here

Code:
While True
                ' Set the event to nonsignaled state.
                allDone.Reset()

                ' Start an asynchronous socket to listen for connections.

                listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), listener)

                ' Wait until a connection is made and processed before continuing.

                allDone.WaitOne()
            End While

put that in a funtion and call that function in a new thread.

Christiaan Baes
Belgium

My Blog
 
Thanks, i have put the code you said in a function and am running that on a separate thread and now the programme doesnt crash any more and runs perfectly.

However, how would i now stop the thread running? (so that the app will stop listening for messages ) ?

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top