简体   繁体   English

C# 异步客户端套接字示例

[英]C# Asynchronous Client Socket Example

I'm looking at an example of the client socket on Microsofts website and I dont understand how this code is async.我正在查看 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();  

The waitone blocks the current thread until the current waithandle receives a signal. waitone 阻塞当前线程,直到当前 waithandle 收到信号。

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

Also is it possible to write this code using task and wait?是否可以使用任务和等待编写此代码?


When I try to make the SocketAsync with ReceiveAsync I dont seem to be able to await the RecieveAsync .当我尝试使用 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);
        
    }

The socket examples on Microsoft's website are known to be extremely bad.众所周知,微软网站上的套接字示例非常糟糕。 The way async is done here is pointless.异步在这里完成的方式毫无意义。 Async is supposed to not consume a thread (for resource management reasons).异步应该不消耗线程(出于资源管理原因)。 This does consume a thread.这确实消耗了一个线程。 This is purely worse than synchronous IO.这纯粹是比同步 IO 更糟糕。

Modern async IO is done using async/await.现代异步 IO 是使用 async/await 完成的。 It can be this simple:可以这么简单:

await socket.ReceiveAsync(...);

This is using true async IO based on tasks.这是使用基于任务的真正异步 IO。 There are more details to this but I hope this gets you oriented in the right direction.对此有更多详细信息,但我希望这能让您朝着正确的方向前进。


One key point is to "find" the modern Task-based socket APIs.一个关键点是“找到”现代基于任务的套接字 API。 Socket has legacy APIs for compatibility reasons.出于兼容性原因, Socket具有传统 API。 In the code snipped posted in the question, this is an EAP-style API which, while not entirely obsolete, is something that almost never should be used.在问题中发布的代码中,这是一个 EAP 风格的 API,虽然没有完全过时,但几乎永远不应该使用它。

So you have to pick the correct overloads.所以你必须选择正确的重载。 Look at intellisense or documentation to see what is there.查看智能感知或文档以了解其中的内容。 You want something that returns a task.您想要返回任务的东西。 Here is a self-contained example:这是一个独立的示例:

        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);

Using sockets correctly is still a bit more involved than this.正确使用套接字仍然比这更复杂。 Unfortunately, it's more than this margin will contain.不幸的是,它超出了这个边距所包含的范围。 So I encourage you to research sockets a bit more.所以我鼓励你多研究一下套接字。 Hope this helps you get started.希望这可以帮助您入门。

Try to use a modern style with modern APIs and modern patterns.尝试使用具有现代 API 和现代模式的现代风格。 They are much better.他们好多了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM