首页 > 解决方案 > C# 异步客户端套接字示例

问题描述

我正在查看 Microsoft 网站上的客户端套接字示例,但我不明白这段代码是如何异步的。

// Connect to the remote endpoint.  
client.BeginConnect(remoteEP,

new AsyncCallback(ConnectCallback), client);

connectDone.WaitOne();

//Send test data to the remote device.
Send(client, "This is a test<EOF>");

sendDone.WaitOne();  

waitone 阻塞当前线程,直到当前等待句柄接收到信号。

https://docs.microsoft.com/en-us/dotnet/framework/network-programming/asynchronous-client-socket-example

也可以使用任务编写此代码并等待吗?


当我尝试使用 ReceiveAsync 制作 SocketAsync 时,我似乎无法等待 RecieveAsync 。

    private async Task<bool> handleReceiveAsync()
    {
        // Get size of frame
        byte[] frameLenData = new byte[4];
        uint frameLen = 0;
        
            bool bOperationFailed = false;
            SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
            socketEventArg.SetBuffer(frameLenData, 0, 4);
            socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
            {
            });
          
            return await _socket.ReceiveAsync(socketEventArg);
        
    }

标签: c#

解决方案


众所周知,Microsoft 网站上的套接字示例非常糟糕。在这里完成异步的方式毫无意义。异步应该不消耗线程(出于资源管理原因)。这确实消耗了一个线程。这纯粹比同步 IO 差。

现代异步 IO 是使用 async/await 完成的。可以这么简单:

await socket.ReceiveAsync(...);

这是使用基于任务的真正异步 IO。这有更多细节,但我希望这能让你朝着正确的方向前进。


一个关键点是“找到”现代的基于任务的套接字 API。Socket出于兼容性原因具有旧版 API。在问题中截断的代码中,这是一个 EAP 风格的 API,虽然并非完全过时,但几乎不应该使用。

所以你必须选择正确的重载。查看智能感知或文档以了解其中的内容。您想要返回任务的东西。这是一个独立的示例:

        using var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);

        await socket.ConnectAsync("example.org", 80);

        await socket.SendAsync(Encoding.ASCII.GetBytes("GET / HTTP/1.0\r\n\r\n"), SocketFlags.None);

        await using var result = new MemoryStream();
        await using var networkStream = new NetworkStream(socket);
        await networkStream.CopyToAsync(result);

        var responseString = Encoding.UTF8.GetString(result.ToArray());

        Console.WriteLine(responseString);

正确使用套接字仍然比这更复杂。不幸的是,它超出了这个边距所包含的范围。所以我鼓励你多研究套接字。希望这可以帮助您入门。

尝试使用具有现代 API 和现代模式的现代风格。他们好多了。


推荐阅读