Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 取消套接字接收请求的最佳方式是什么?_C#_.net - Fatal编程技术网

C# 取消套接字接收请求的最佳方式是什么?

C# 取消套接字接收请求的最佳方式是什么?,c#,.net,C#,.net,在C#中,有3种方法可以尝试在套接字上接收TCP数据: Socket.Receive是一种同步的阻塞方法。除非失败或[可选]超时,否则它不会返回,直到成功 Socket.BeginReceive是异步的,当有数据要接收时,使用现在过时的开始/结束模式调用提供的回调/委托 Socket.ReceiveAsync开始接收数据的异步请求 然而,我的理解是,这些实际上都不允许您取消接收操作?文档建议使用EndReceive来完成读取,而不是可以调用来终止请求的东西 您经常看到这样的代码 while(so

在C#中,有3种方法可以尝试在
套接字上接收TCP数据:

  • Socket.Receive
    是一种同步的阻塞方法。除非失败或[可选]超时,否则它不会返回,直到成功
  • Socket.BeginReceive
    是异步的,当有数据要接收时,使用现在过时的开始/结束模式调用提供的回调/委托
  • Socket.ReceiveAsync
    开始接收数据的异步请求
  • 然而,我的理解是,这些实际上都不允许您取消接收操作?文档建议使用
    EndReceive
    来完成读取,而不是可以调用来终止请求的东西

    您经常看到这样的代码
    while(socket.Available==0&&!cancel)睡眠(50);如果(!取消)套接字接收(…)

    但那太可怕了

    如果我想坐在那里等待数据,但在某个时候取消了接收,比如说用户点击了“停止”按钮,那么如何才能做到这一点,这样我就不会在以后发生意外时触发回调


    我曾想知道是否要关闭套接字,这会导致接收操作失败,但这似乎有点难看。我的思路是否正确,或者上面列出的各种API方法是否允许直接取消,这样我就不会冒险挂起异步操作?

    没有已知的方法来取消它(AFAIK)

    您可以做一件事,设置
    Socket.Blocking=false
    。当没有数据时,receive将立即返回。这样它就不会挂起来

    你应该检查一下酒店


    我建议您使用
    BeginReceive(IList)来接收0个字节(使用静态字节[]emptyBuffer=new byte[0]),如果sockerError返回一个'will block',您可以有一个短暂的延迟,然后重试。当它不返回socketError时,可能有数据。因此您可以启动一个异步版本。

    没有所谓的延迟“TCP接收呼叫/请求”。TCP处理任意方向的数据包,而不是HTTP之类的请求和响应。您到底想知道什么?您是否只想突破阻塞
    socket.receive()
    method call?关闭套接字这样做有什么不对?我不知道有什么不对,这就是我问的原因。故意导致操作失败似乎有点……不雅观。比如让朋友把一棵树倒在我的车前面,让它停下来:)是的,套接字很难看。哈。这就是我问的原因——也许这是一种正常的方式,但不是直观的。虽然我发现如果我这样做,我不会失败,但成功地从阻塞调用接收到0字节。我期待着
    SocketException
    没有办法取消挂起的异步I/O。Windows内核确实支持是(通过
    CancelIoEx
    ),但这是一项相对较新的发明,在.NET中没有出现(据我所知)--即使这样,它也不适用于套接字。通常的方法是指定一个且只有一个“接收循环”来完成所有通信,并通过关闭套接字来“取消”(即,您完全完成了)。如果需要可中断的读取,请将其设置为接收循环发送到队列或发出事件信号,然后仅等待。具有零字节缓冲区的
    receive
    调用将始终失败,因为无法成功通信(返回值0表示连接正常关闭,而不是未读取任何字节)。因此,您可以使用
    套接字。可用的
    。我不建议任何人使用它,也不建议一般使用非阻塞套接字。我不知道
    套接字。阻塞
    知道这一点非常有用,因为即使
    ReceiveAsync
    方法也不允许IIRCcancellation@JeroenMostert结果是零字节,但是在检查收到的字节之前,您必须先检查错误代码。
    int zeroBytes=\u socket.Receive(新字节[0],0,0,SocketFlags.None,out var errorCode);
    if(errorCode==SocketError.WouldBlock){//等待并重试}
    这将不是最优的,因为应该指定重试的延迟时间。它不会比使用阻塞更为最优。但是,在2020年,通过关闭套接字取消
    BeginReceive
    。Oef…仍然在2021年通过关闭套接字取消
    BeginReceive
    。为什么没有人知道这一点?我们可以为您发送图片从火星到地球,但是如果我们不能及时得到数据,我们不能取消UDP接收。