在 C# 5 中使用 async/await 模式编写高度可扩展的 TCP/IP 服务器?

Posted

技术标签:

【中文标题】在 C# 5 中使用 async/await 模式编写高度可扩展的 TCP/IP 服务器?【英文标题】:Writing a highly scalable TCP/IP server in C# 5 with the async/await pattern? 【发布时间】:2013-01-15 17:45:36 【问题描述】:

我的任务是设计一个相当简单的 TCP/IP 服务器,它必须接受来自多个客户端的连接。它需要用 C# 编写,我使用的是 .NET 4.5。也就是说,我不确定 .NET 4.5 中 TCP/IP 服务器/客户端可扩展性的当前“最新技术”是什么。

我确实看到了这个帖子:How to write a scalable Tcp/Ip based server。但这与 .NET 2.0 和 3.5 相关,并且没有提及 async/await 模式。

我能够以“旧方式”编写服务器......但我想知道“新方式”是什么。

使用 Socket、TcpClient 或 TcpListener 上的新 Async 方法在 C# 中创建可扩展服务器的最佳方式是什么? 新的异步方法是否利用 I/O 完成端口? 滚动您自己的 Socket 侦听器效率更高,还是 TcpListener/TcpClient 类现在非常好?

编辑:其他问题。

【问题讨论】:

没有 C# 4.5 :) 它是 .net 4.5,C# 5 这可能有用 - blogs.msdn.com/b/pfxteam/archive/2011/12/15/10248293.aspx @SoroushFalahati:使用 I/O 完成端口的异步不应阻塞线程。事实上,.NET 3.5 和更高版本中的大多数 Begin/AsyncResult 类型的 I/O 方法都利用 IOCP,因此它们不应该像 .NET 2.0 中的异步那样阻塞任何线程。 @SoroushFalahati:实际上,我很确定绝大多数浏览器和 Web 服务器都使用 asynchronous 方法。特别是基于 IOCP。 您是否考虑过使用networkcomms.net等网络库?这里有一个很好的例子networkcomms.net/creating-a-wpf-chat-client-server-application 【参考方案1】:

在 Socket、TcpClient 或 TcpListener 上使用新的 Async 方法在 C# 中创建可扩展服务器的最佳方式是什么?

Socket 上没有任何新的 async 方法; Socket 上名为 *Async 的方法是一组特殊的 API,用于减少内存使用。 TcpClientTcpListener 确实得到了一些新的 async 方法。

如果您想要最好的可扩展性,最好使用Stephen Toub's custom awaiters for Socket。如果您想要最简单的代码,最好使用TcpClientTcpListener

新的异步方法是否利用 I/O 完成端口?

是的,就像 BCL 中的大多数其他异步 API 一样。 AFAIK,Stream 类是唯一可能不使用 IOCP 的类;所有其他 *Begin/*End/*Async 方法都使用 IOCP。

滚动您自己的 Socket 侦听器效率更高,还是 TcpListener/TcpClient 类现在非常好?

这些课程非常好。 Stephen Toub 有一个blog post,它在内存使用方面效率更高。

【讨论】:

与问题无关,什么是IO Completion port?对不起,VB背景让我没有遇到这个。谢谢。 @StaurtDunkeld 链接了上面的那篇文章。我看了看它,我想我没有注意到它试图创建一个更有效的侦听器/客户端。我试图了解是什么使它更高效的内存。是不是你不需要实例化一个 TcpClient 并保留它来管理连接? @shahkalpesh:An efficient way to handle lots of asynchronous I/O。 .NET 目前每个应用程序域使用一个 IOCP,绑定到线程池。 @blesh:不;这是因为它使用了 Socket *Async 方法。通常,异步操作需要为每个操作分配一个结构(IAsyncResult,类似于OVERLAPPED)。 Socket *Async 方法使用SocketAsyncEventArgs,有点像可重复使用的IAsyncResult。因此分配/解除分配更少,对 GC 的压力也更小。 感谢您的回答。我想我要做的是使用 TcpListener/TcpClient 并将它们抽象出来,所以如果我以后需要使用 Toub 的方法进行优化,我可以。

以上是关于在 C# 5 中使用 async/await 模式编写高度可扩展的 TCP/IP 服务器?的主要内容,如果未能解决你的问题,请参考以下文章

理解 C# 5 async/await 中的上下文

C# 异步操作 async await 的用法

python 3.5 中的 async/await 关键字是不是受到 C# 中的 async/await 的启发? [关闭]

C# 中await和async的作用

C# 中await和async的作用

C# Async与Await的使用