gpt4 book ai didi

.net - 如何停止从 NetworkStream 读取?

转载 作者:行者123 更新时间:2023-12-03 14:36:22 30 4
gpt4 key购买 nike

我正在尝试从 NetworkStream 中读取数据。我写下一个代码:

Imports System.Net
Imports System.Net.Sockets

Public Class Form1
Dim tcpclnt1 As New TcpClient
Dim streamTcp1 As NetworkStream
Dim DataBuffer(1024) As Byte 'Buffer for reading
Dim numberOfBytes As Integer
' event for reading data from stream
Dim evtDataArrival As New AsyncCallback(AddressOf DataProcessing)

Private Sub Btn_Connect5000_Click(sender As Object, e As EventArgs)_
Handles Btn_Connect5000.Click
' Connecting to server
tcpclnt1 = New TcpClient
tcpclnt1.Connect("192.168.1.177", 5000)
streamTcp1 = tcpclnt1.GetStream() 'Create stream for current tcpClient
' HERE WE START TO READ
streamTcp1.BeginRead(DataBuffer, 0, DataBuffer.Length, evtDataArrival, Nothing)

End Sub

Public Sub DataProcessing(ByVal dr As IAsyncResult)
numberOfBytes = streamTcp1.EndRead(dr) 'END READ
' ...HERE SOME ROUTINE FOR PRINT DATA TO TEXTBOXES...
'START NEW READING
streamTcp1.BeginRead(DataBuffer, 0, DataBuffer.Length, evtDataArrival, Nothing)
End Sub

Private Sub Btn_Disconnect5000_Click(sender As Object, e As EventArgs)_
Handles Btn_Disconnect5000.Click
' Disconnect from port 5000. Close TcpClient
streamTcp1.Dispose()
streamTcp1.EndRead(Nothing) 'And here mistake appears !!!
streamTcp1.Close()
tcpclnt1.Close()
End Sub
End Class

问题:我创建了新客户端和新流。据我所知,通过使用 BeginRead 它开始在新线程中读取数据。因此,为了实时数据,我在 DataProcessing 函数的末尾开始了新的 BeginRead。但是我在尝试断开连接时遇到了问题(查看 Btn_Disconnect5000_Click 函数):我尝试关闭流和客户端,但它仍然尝试读取 DataProcessing 方法并告诉我:

Cannot access a disposed object

(感谢 djv 的正确翻译!)

所以我想我需要先停止线程,但不知道该怎么做:我尝试了 Dispose() 方法,先尝试关闭流但仍然不能。我也尝试手动调用 EndRead 方法,但无法理解我必须将什么作为参数分配给它。

最佳答案

EndRead 实际上并没有停止异步读取。它获取读取的字节数,结束当前 读取操作并抛出操作期间可能发生的任何异常。因此调用它不会阻止进一步的异步操作发生。

我建议您在回调中插入一个空检查,这将退出该方法并阻止 BeginRead 被调用更多。

Public Sub DataProcessing(ByVal dr As IAsyncResult)
If streamTcp1 Is Nothing Then _
Return 'Stream is disposed, stop any further reading.

numberOfBytes = streamTcp1.EndRead(dr)

正如 the_lotus 所说,您可能还需要添加异常处理,因为如果您不够幸运,streamTcp1 可能会在通过 null 检查后被处置。

你应该在回调中检查流的原因是,正如我们所讨论的,在“关闭”一个 TCP 连接后,它进入了 CLOSE_WAITTIME_WAIT 或以下之一FIN_* 状态,以便操作系统仍然可以将延迟/重传的数据包映射到它。

NetworkStream.BeginRead() 最终调用 WSARecv它在 native 端注册了一个异步操作,因此它不知道您的套接字是否已处理,因为它只关心连接是否处于事件状态(CLOSE_WAITTIME_WAIT 连接仍然被认为对操作系统有效)。这可能会导致回调被调用,即使套接字/流已被释放。

关于.net - 如何停止从 NetworkStream 读取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43096943/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com