【问题标题】:SocketAsyncEventArgs - how to detect socket operation in progress & terminate?SocketAsyncEventArgs - 如何检测正在进行的套接字操作并终止?
【发布时间】:2017-06-13 16:44:27
【问题描述】:

我有时会收到此错误:

已使用此 SocketAsyncEventArgs 实例进行异步套接字操作。

...当我尝试拨打 SocketServiceEventArgs.SetBuffer()

我意识到这是因为一个实例只能执行一个操作并且它必须处于使用状态。但是我再次调用它,因为在客户端之前的超时之后,我希望尝试重新发送请求。我不希望关闭此套接字并使用新的套接字,因为这样与客户端的连接将中断。

但是,我需要做的是在执行此操作之前检查另一个操作是否已经在进行,如果是,则终止它,以便我可以再次发送。

我用来发送的代码是

saeaCommunicationObject.AcceptSocket.SendAsync(saeaCommunicationObject)

但更有可能正在进行的是接收

saeaCommunicationObject.AcceptSocket.ReceiveAsync(saeaCommunicationObject))

saeaCommunicationObjectSocketAsyncEventArgs)。

在研究中,我遇到过

AcceptSocket.EndReceive(IAsyncResult asyncResult)

但我不确定这是否正确,而且我不知道从哪里获得 asyncResult(所以如果这是正确的,我的问题是,这应该来自哪里?)

那么我可以做些什么来检查它是否正在进行中(如果是,则终止它)?

编辑

我看过的一个地方建议(但不推荐)使用 P/Invoke 使用 CancelIoEx() - 但是我无法让它工作,而且关于此的文档很少。

[DllImport("kernel32.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CancelIoEx(IntPtr hFile);

private void CancelReceive() {
   bool result = CancelIoEx(saeaCommunicationObject.AcceptSocket.Handle)
   // etc.
}

我得到result = false。我也试过CancelIo(),当我得到result = true时,当我尝试调用SetBuffer()时,会抛出同样的异常。

TL;DR

一旦调用了ReceiveAsync(),那么现在套接字正在等待输入以触发Completed 事件,我该如何取消这个请求?

【问题讨论】:

  • 你有没有想过这个问题?

标签: c# sockets


【解决方案1】:

来自 MSDN:

如果 I/O 操作处于挂起状态,则返回 true。 e 参数上的 SocketAsyncEventArgs.Completed 事件将在操作完成后引发。 如果 I/O 操作同步完成,则返回 false。在这种情况下,不会引发 e 参数上的 SocketAsyncEventArgs.Completed 事件,并且可以在方法调用返回后立即检查作为参数传递的 e 对象以检索操作结果。

因此,您应该检查ReceiveAsync 调用的返回值。如果它的true 订阅SocketAsyncEventArgs.Completed 事件。如果为假,则立即检查SocketAsyncEventArgs 以验证结果。

【讨论】:

  • 谢谢,但如果它处于待处理状态(我认为这意味着它正在等待来自客户端的输入),我想取消它。而且,如果它不是待处理的,我不想让它待处理。
  • 抱歉,我无法编辑评论,但是:我想检查 ReceiveAsync() 是否已被调用。 (即它已经挂起)。如果是这样,则取消此操作。如果我只是再次调用ReceiveAsync() 进行检查,那么我会得到同样的异常,但这次来自这个调用(而不是SetBuffer())。
【解决方案2】:

对具体问题的回答并不完全,但我目前的解决方法是检查AcceptSocket.BytesAvailable 的值并等待它> 0,然后再调用ReceiveAsync()。这样,如果我需要先调用SendAsync(),它可以被中断。

我认为这会有点低效率,我不确定它的可扩展性,考虑到可能有多达 50 个客户端同时连接 - 但它似乎让我克服了这个困难现在。

【讨论】:

    猜你喜欢
    • 2015-05-23
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-22
    相关资源
    最近更新 更多