c# - 取消套接字接收请求的最佳方法是什么?

标签 c# .net

在 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/

    相关文章:

    .net - 连接到数据库仍然更昂贵吗?

    c# - Lync UCMA SDK Server - 全局订阅所有 Presentities 的状态更新

    c# - 错误 : No overload for method "ToString" takes 1 arguments

    c# - 每个进程是否只有一个静态变量实例?

    c# - 如何在 WPF 中刷新/重新加载数据网格?

    C# App.config 与设置文件

    c# - 根级别的数据无效

    c# - 隐藏的 int 属性验证

    c# - 处理sql异常的策略应该是什么?

    c# - 无法使用 json 和 ajax 调用从 webservice 方法获得响应