在 C# 中,您有 3 种方法可以尝试在 Socket
上接收 TCP 数据。 :
Socket.Receive
是一种同步的阻塞方法。它在成功之前不会返回,除非失败或 [可选] 超时。 Socket.BeginReceive
是异步的,当有数据要接收时调用提供的回调/委托(delegate),使用现在过时的开始/结束模式Socket.ReceiveAsync
开始异步请求接收数据但是我的理解是这些实际上都没有让您取消接收操作吗?文档建议
EndReceive
用于完成读取,而不是可以调用来终止请求的东西?你经常看到像这样的代码
while(socket.Available==0 && !cancel)Sleep(50); if(!cancel)socket.Receive(...);
但这太可怕了。
如果我想坐下来等待数据但在某些时候取消接收,说用户点击“停止”按钮,如何巧妙地完成,这样我就不会在意外时触发回调?
我想知道关闭套接字会导致接收操作失败,但它看起来有些难看。我是按照正确的思路思考还是上面列出的各种 API 方法允许直接取消,这样我就不会冒着悬空异步操作的风险?
最佳答案
没有已知的方法可以取消它(AFAIK)
你可以做的一件事就是设置Socket.Blocking = false
.当没有数据时,receive 会立即返回。这样就不会挂了。
您应该检查 Socket.Blocking属性(property)。
我建议您使用 BeginReceive(IList<ArraySegment<Byte>>, SocketFlags, SocketError, AsyncCallback, Object)
重载以防止它抛出异常。
检查“Would Block”上的 SocketError,意思是“没有数据”。所以你可以再试一次。
没有测试但是->
一个好主意是使用非异步版本 Receive接收 0 个字节(使用静态 byte[] emptyBuffer = new byte[0]),如果 sockerError 返回“将阻塞”,您可以有一个短暂的延迟并重试。当它不返回 socketError 时,可能有数据。所以你可以启动一个异步版本。
关于c# - 取消套接字接收请求的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60083939/