Socket.EndAccept 抛出 ArgumentException

Socket.EndAccept throwing ArgumentException

使用 .NET 6.0。

我这样调用了 BeginAccept:

AsyncCallback callback = new AsyncCallback(AcceptCallback);
object? state = this.listenSocket;
_ = this.listenSocket.BeginAccept(callback, state);

并且我的 AcceptCallback 方法按预期被调用。然后我必须调用 EndAccept 来获取接收套接字:

    private static void AcceptCallback(IAsyncResult result)
    {
        Socket? listenSocket = result.AsyncState as Socket;

        if (listenSocket == null)
        {
            // note: This is impossible but it helps getting the possible
            //       null reference warnings out of the way.
            throw new ArgumentNullException(nameof(result.AsyncState), "The state object is null.");
        }

        Socket receiveSocket = listenSocket.EndAccept(
            out byte[] buffer,
            out int bytesRead,
            result);  // and here it blows up

最后一个电话给我一个“System.ArgumentException:'值不在预期范围内。(参数'asyncResult')'”。

显然最后一个参数有问题。这不是我提供的东西,它是系统传递给我的结果参数,它(根据调试器)是一个正确的 System.Threading.Tasks.TaskToApm.TaskAsyncResult。我只是按照我找到的示例进行操作。

我一开始在 BeginAccept 的调用中没有包装 new AsyncCallback() 因为我不明白它有什么好处(虽然我想知道)。我最初也有非静态方法。因为我遇到了这个问题,所以我将其更改为更像原始示例,但仍然存在相同的异常。

问题是什么,我该怎么做才能克服它?

[编辑]

正如 Hans Passant 所指出的,结果参数不应该是 System.Threading.Tasks.TaskToApm.TaskAsyncResult,这会导致错误。互联网上几乎没有关于 TaskAsyncResult 的讨论或文档,这让我产生了怀疑,认为这可能是新框架代码中的错误。所以我用 .NET 5.0 重建,但结果是一样的。

我只是在使用 System.Net.Sockets.Socket 类,没有什么特别的自定义库或类似的东西。

第一位出现:

AsyncCallback callback = new AsyncCallback(AcceptCallback);
object? state = this.listenSocket;
_ = this.listenSocket.BeginAccept(callback, state);

让它失败。如果我将其更改为:

int maxSize = 0x2000;  // 8K
AsyncCallback callback = new AsyncCallback(AcceptCallback);
object? state = this.listenSocket;
_ = this.listenSocket.BeginAccept(maxSize, callback, state);

它成功了,在 EndAccept 上不再有异常,我在 ReceiveCallback 中获得了预期的数据(异步流程的下一步)。

因为我是套接字编程的新手,所以我认为从简单开始是明智的,所以我使用参数最少的 BeginAccept 重载。我假设它会使用默认的最大尺寸。好吧,无论那个“简单”的重载做什么,都不好。

所以 AcceptCallback 的结果参数的类型 System.Threading.Tasks.TaskToApm.TaskAsyncResult 完全没问题,那里没有问题(我检查过,它仍然是一样的)。

我可以继续了。