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