vb.net异步流写/读问题

时间:2016-11-01 18:20:48

标签: vb.net asynchronous

我在过去几天一直在努力解决一个问题,但是我似乎无法让它正常工作。

我有多个客户端连接到服务器,服务器需要保留已连接客户端的列表,如果客户端断开连接,则将其从列表中删除,我有一点正常工作。

一旦客户端连接,服务器可以通过发送客户端以2字节数据响应的几个字节的数据来调用客户端以获取有关其状态的一些信息。根据此响应,服务器将完成许多不同任务中的任何一个。

我有同步工作,但现在我正在尝试使函数异步,我正在遇到一个问题。我可以告诉我的功能,在客户端响应并返回错误数据之前,请求客户端的信息完成,如果我打印从客户端收到的数据,我可以看到它是正确的信息。

这是我第一次使用异步函数和连接,所以我很可能完全错了,我已经查看了很多示例代码,但我似乎找到了任何可以解决我的问题。< / p>

这就是我现在所拥有的:

  'create the collection instance to store connected clients
    Private clients As New List(Of TcpClient)
    'declare a variable to hold the listener instance
    Private listener As TcpListener
    'declare a variable to hold the cancellation token source instance
    Private tokenSource As CancellationTokenSource
    Private recvTsk As Task
    Private Rreply As New List(Of Byte)



    Private Async Sub startTCPListenerServer()

'get port from ini file
        Dim netPort = SettingsIniFile.GetString("Setup", "NetworkPort", "")



        While True
            'create a new cancellation token source instance
            tokenSource = New CancellationTokenSource
            'create a new listener instance bound to the desired address and port
            listener = New TcpListener(IPAddress.Any, netPort)
            'start the listener
            listener.Start()
            While True
                Try
                    Dim client As TcpClient = Await listener.AcceptTcpClientAsync

                    clients.Add(client)
                    Dim clientIP As String = client.Client.RemoteEndPoint.ToString
                    ListBox1.Items.Add(clientIP)



                    Try
                        'begin reading from the client's data stream
                        Using stream As NetworkStream = client.GetStream
                            Dim buffer(client.ReceiveBufferSize - 1) As Byte
                            Dim read As Integer = 1

                            'if read is 0 client has disconnected
                            While read > 0

                                recvTsk = New Task(Sub()

                                                       For i = 0 To read - 1

                                                           'data recived at this point is correct 
                                                           Rreply.Add(buffer(i))
                                                       Next


                                                   End Sub, tokenSource.Token)


                                read = Await stream.ReadAsync(buffer, 0, buffer.Length, tokenSource.Token)

                                recvTsk.Start()

                            End While
                            'client gracefully closed the connection on the remote end
                        End Using
                    Catch ocex As OperationCanceledException
                        'the expected exception if this routines's async method calls honor signaling of the cancelation token
                        '*NOTE: NetworkStream.ReadAsync() will not honor the cancelation signal
                    Catch odex As ObjectDisposedException
                        'server disconnected client while reading
                    Catch ioex As IOException
                        'client terminated (remote application terminated without socket close) while reading
                    Finally
                        'ensure the client is closed - this is typically a redundant call, but in the
                        'case of an unhandled exception it may be necessary
                        'remove the client from the list of connected clients
                        clients.Remove(client)

                        client.Close()
                        ListBox1.Items.Remove(clientIP)

                        'remove the client's task from the list of running tasks
                        'clientTasks.Remove(client.Task)
                    End Try


                Catch odex As ObjectDisposedException
                    'listener stopped, so server is shutting down
                    Exit While
                End Try

            End While


            For i As Integer = clients.Count - 1 To 0 Step -1
                clients(i).Close()
            Next
            tokenSource.Dispose()

        End While

        'signal any processing of current clients to cancel (if listening)
        tokenSource.Cancel()
        'abort the current listening operation/prevent any new connections
        listener.Stop()
        'End If


    End Sub



    Async Function sendToPod(message() As Byte, podNum As Integer) As Task(Of Byte)

        If clients.Count = 0 Then

        Else
            Dim podIP As String

'get ip address as string from ini file
                podIP = SettingsIniFile.GetString("NetworkSettings", "Pod" & podNum & "IP", "")


            Dim currentClient As TcpClient = Nothing

            For Each client As TcpClient In clients

                Dim clientIP As String = (CType(client.Client.RemoteEndPoint, IPEndPoint).Address.ToString())

                If clientIP = podIP Then
                    currentClient = client
                End If
            Next

            If currentClient IsNot Nothing Then

                'get the current client, stream, and data to write

                Dim stream As NetworkStream = currentClient.GetStream


                Dim buffer() As Byte = message

                'wait for the data to be sent to the remote 

                Await stream.WriteAsync(buffer, 0, buffer.Length)


                recvTsk.Wait()

                Return Rreply(1)

            End If

        End If


    End Function

    Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Try
            Me.TextBox1.Text = Await sendToPod({"&HAB", "&HAD", "&HFF", "&HFF"}, 1)
        Catch
        End Try
    End Sub
End Class

0 个答案:

没有答案