问题描述
我想在向服务器发送数据后立即得到数据响应,这是我的代码,NetworkStream.DataAvailable 总是返回 false,我无法从 NetworkStream 读取数据:
Public Async Function SendAndGetReply(ByVal data() As Byte,Optional ByVal timeout As Integer = 1000) As Task(Of Byte())
Dim buffer(4095) As Byte
Dim bytesRead As Integer = 0
Dim stream As NetworkStream = client.GetStream()
Using writeCts = New CancellationTokenSource(timeout)
Await stream.WriteAsync(data,data.Length,writeCts.Token)
Await stream.FlushAsync()
Try
Using memoryStream As New MemoryStream()
Do
Debug.Print(stream.DataAvailable.ToString)
bytesRead = Await stream.ReadAsync(buffer,buffer.Length)
memoryStream.Write(buffer,bytesRead)
Loop While bytesRead = 0
End Using
Catch ex As Exception
Debug.Print(ex.Message.ToString)
End Try
End Using
Return buffer.Take(bytesRead).ToArray
End Function
全班:
Public Delegate Sub TcpClientsEventHandler(Of TEventArgs)(ByVal sender As Object,ByVal e As TEventArgs)
Public Delegate Sub TcpClientsEventHandler(ByVal sender As Object)
Private client As TcpClient
Private listener As TcpListener
Private tasks As New List(Of Task)()
Public Event OnConnect As TcpClientsEventHandler
Public Event Ondisconnect As TcpClientsEventHandler
Public Event OnDataReceived As TcpClientsEventHandler(Of Byte())
Public BufferSize As Integer = 4096
Public ReadOnly Property RemoteEndPoint() As EndPoint
Get
If client Is nothing Then
Throw New InvalidOperationException("Client is not connected")
End If
Return client.Client.RemoteEndPoint
End Get
End Property
Private Sub New(ByVal client As TcpClient)
Me.client = client
End Sub
Public Sub New(ByVal hostname As String,ByVal port As Integer)
CheckServerUsedAsClient()
CheckClientAlreadyConnected()
client = New TcpClient()
client.Connect(hostname,port)
client.NoDelay = True
CallOnConnect()
StartReceiveFrom()
End Sub
Public Sub Connect(ByVal address As IPAddress,ByVal port As Integer)
CheckServerUsedAsClient()
CheckClientAlreadyConnected()
client = New TcpClient()
client.Connect(address,port)
CallOnConnect()
StartReceiveFrom()
End Sub
Public Sub disconnect()
CheckServerUsedAsClient()
CallOndisconnect()
client.Close()
End Sub
Public Sub Start(ByVal port As Integer)
Start(IPAddress.Any,port)
End Sub
Public Sub Start(ByVal address As IPAddress,ByVal port As Integer)
CheckClientUsedAsServer()
CheckServerAlreadyStarted()
listener = New TcpListener(address,port)
listener.Start()
StartListen()
End Sub
Public Sub Close()
CheckClientUsedAsServer()
listener.Stop()
Task.WhenAll(tasks).Wait()
End Sub
Public Sub SendData(ByVal data() As Byte)
CheckServerUsedAsClient()
client.GetStream().Write(data,data.Length)
End Sub
Private Sub CallOnDataReceived(ByVal data() As Byte)
RaiseEvent OnDataReceived(Me,data)
End Sub
Private Sub CallOnConnect()
RaiseEvent OnConnect(Me)
End Sub
Private Sub CallOndisconnect()
RaiseEvent Ondisconnect(Me)
End Sub
Private Sub CheckServerUsedAsClient()
If listener IsNot nothing Then
Throw New InvalidOperationException("Cannot use a server connection as a client")
End If
End Sub
Private Sub CheckClientUsedAsServer()
If client IsNot nothing Then
Throw New InvalidOperationException("Cannot use a client connection as a server")
End If
End Sub
Private Sub CheckServerAlreadyStarted()
If listener IsNot nothing Then
Throw New InvalidOperationException("Server is already started")
End If
End Sub
Private Sub CheckClientAlreadyConnected()
If client IsNot nothing Then
Throw New InvalidOperationException("Client is already connected")
End If
End Sub
Private Sub StartListen()
tasks.Add(ListenAsync())
End Sub
Private Async Function ListenAsync() As Task
Do
Dim client As TcpClient = Await listener.AcceptTcpClientAsync()
Dim connection As New TcpClients(client)
StartReceiveFrom()
RaiseEvent OnConnect(Me)
Loop
End Function
Private Sub StartReceiveFrom()
tasks.Add(ReceiveFromAsync())
End Sub
Private Async Function ReceiveFromAsync(Optional ByVal timeout As Integer = 5000) As Task
Try
client.Client.ReceiveTimeout = timeout
Dim stream As NetworkStream = client.GetStream()
Dim buffer(BufferSize - 1) As Byte
Dim ms As New MemoryStream()
do while client.Client.Connected
Dim bytesRead As Integer = Await stream.ReadAsync(buffer,buffer.Length)
ms.Write(buffer,bytesRead)
If Not stream.DataAvailable Then
CallOnDataReceived(ms.ToArray())
ms.Seek(0,SeekOrigin.Begin)
ms.SetLength(0)
End If
Loop
Catch
End Try
End Function
Public Async Function SendAndGetReply(ByVal data() As Byte,bytesRead)
Loop While bytesRead = 0
End Using
Catch ex As Exception
Debug.Print(ex.Message.ToString)
End Try
End Using
Return buffer.Take(bytesRead).ToArray
End Function
结束课程
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)