Csharp/C#教程:使用TcpListener进行异步/等待或开始/结束?分享


使用TcpListener进行异步/等待或开始/结束?

我已经开始构建一个tcp服务器,它将能够接受许多客户端,并同时从所有客户端接收新数据。

到目前为止,我使用IOCP用于tcp服务器,这非常简单和舒适,但这次我想使用Async / Await技术。 那是在C#5.0中发布的。

问题是,当我开始使用async / await编写服务器时,我发现在tcp中有多个用户服务器用例,async / await tech。 并且常规同步方法将起作用。

这是一个更具体的简单示例:

class Server { private TcpListener _tcpListener; private List _clients; private bool IsStarted; public Server(int port) { _tcpListener = new TcpListener(new IPEndPoint(IPAddress.Any, port)); _clients = new List(); IsStarted = false; } public void Start() { IsStarted = true; _tcpListener.Start(); Task.Run(() => StartAcceptClientsAsync()); } public void Stop() { IsStarted = false; _tcpListener.Stop(); } private async Task StartAcceptClientsAsync() { while (IsStarted) { // ******** Note 1 ******** var acceptedClient = await _tcpListener.AcceptTcpClientAsync(); _clients.Add(acceptedClient); IPEndPoint ipEndPoint = (IPEndPoint) acceptedClient.Client.RemoteEndPoint; Console.WriteLine("Accepted new client! IP: {0} Port: {1}", ipEndPoint.Address, ipEndPoint.Port); Task.Run(() => StartReadingDataFromClient(acceptedClient)); } } private async void StartReadingDataFromClient(TcpClient acceptedClient) { try { IPEndPoint ipEndPoint = (IPEndPoint) acceptedClient.Client.RemoteEndPoint; while (true) { MemoryStream bufferStream = new MemoryStream(); // ******** Note 2 ******** byte[] buffer = new byte[1024]; int packetSize = await acceptedClient.GetStream().ReadAsync(buffer, 0, buffer.Length); if (packetSize == 0) { break; } Console.WriteLine("Accepted new message from: IP: {0} Port: {1}nMessage: {2}", ipEndPoint.Address, ipEndPoint.Port, Encoding.Default.GetString(buffer)); } } catch (Exception) { } finally { acceptedClient.Close(); _clients.Remove(acceptedClient); } } } 

现在,如果您看到“注1”和“注2”下的行,可以很容易地将其更改为:

注1来自

 var acceptedClient = await _tcpListener.AcceptTcpClientAsync(); 

 var acceptedClient = _tcpListener.AcceptTcpClient(); 

并注2

 int packetSize = await acceptedClient.GetStream().ReadAsync(buffer, 0, 1024); 

 int packetSize = acceptedClient.GetStream().Read(buffer, 0, 1024); 

服务器的工作方式完全相同。

那么,为什么在tcp监听器中为多个用户使用async / await,如果它与使用常规同步方法一样?

在这种情况下我应该继续使用IOCP吗? 因为对我而言,它非常简单和舒适,但我担心它会被淘汰,甚至在较新的.NET版本中也没有。

直到现在,我使用IOCP用于tcp服务器,这非常简单和舒适,但这次我想使用Async / Await技术。 那是在C#5.0中发布的。

我认为你需要正确的术语。

使用BeginOperationEndOperation方法称为异步编程模型 (APM)。 具有单个Task (或Task )返回方法称为基于任务的异步模式 (TAP)。 I / O完成端口 (IOCP)是一种在Windows上处理异步操作的方法,使用APM和TAP使用它们的异步I / O方法。

这意味着APM和TAP的性能将非常相似。 两者之间的最大区别在于使用TAP和async代码 – await比使用APM和回调的代码更具可读性。

因此,如果您想(或必须)异步编写代码,请使用TAP和asyncawait ,如果可以的话。 但如果你没有充分的理由这样做,只需同步编写你的代码。

在服务器上,使用异步的一个很好的理由是可伸缩性:异步代码可以同时处理更多的请求,因为它往往使用更少的线程。 如果您不关心可伸缩性(例如,因为您不会同时拥有多个用户),那么异步并没有多大意义。


此外,您的代码包含一些您应该避免的做法:

经过几次搜索,我发现了这一点

:这是TCPServer实践列表,但哪一个是每秒管理5000多个客户端的最佳实践?

:我的假设是“ 编写异步方法 ”,如果你正在使用数据库同时“ 异步方法和迭代器 ”会做更多

这是使用async / await的示例代码。

异步等待tcp服务器

我认为使用async / await比使用iocp更容易构建tcp服务器。

上述就是C#学习教程:使用TcpListener进行异步/等待或开始/结束?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/1012699.html

(0)
上一篇 2021年12月30日
下一篇 2021年12月30日

精彩推荐