tcp/ip多线程通信
介绍性能是大多数服务器应用程序开发人员最关心的问题。 这就是为什么许多人期望使用.NET平台开发高性能服务器应用程序的原因,而不管其提供的安全功能如何。
Microsoft Windows提供了一种高性能模型,该模型使用I / O完成端口(IOCP)处理网络事件。 IOCP提供最佳性能,但由于缺少良好的代码示例以及必须使用C / C ++语言而难以使用。 从另一方面来说,如果服务器的业务逻辑不平凡,那么将很难支持和测试它。 对于开发人员而言,在C ++代码中查找错误可能会成为一个严峻的挑战。
解决办法是什么?理想情况下,我们希望有一个服务器应用程序具有与C ++服务器相当的性能,并以C#编写经过精心设计,无错误,经过单元测试的业务逻辑。 是的,那太好了!
让我们看看.NET平台为网络操作提供了什么。
为了编写可扩展的高性能服务器,支持异步操作的套接字类应该很棒。 根据文档,异步网络操作方法(BeginConnect,BeginReceive,BeginSend)支持I / O完成端口,但是简单的基准测试表明性能仍然很低。 套接字类在异步使用时非常耗资源。
除了几个.NET类的设计和实现问题[i]之外,由于在每次进行底层系统调用时都会发生许多托管/非托管代码转换和数据封送处理,因此完全用.NET编写的服务器还存在性能不足(网络I / O,线程同步等)。 唯一的解决方案是最小化这些过渡。 此方法已在XF.Server组件中使用,该组件最近已发布以供社区预览,并可供公众下载(
http://www.kodart.com/ )在XF.Server组件中,仅当在业务逻辑层和传输逻辑层之间传递消息时,才会发生托管/非托管代码转换。 XF.Server处理所有低级网络I / O,从而为客户端提供接口以进行网络操作。
现在,让我们使用C#编写高性能的简单Web服务器,以便我们可以将性能与其他Web服务器(例如IIS或Apache(用C / C ++编写))进行比较。
[一世]
http://msdn.microsoft.com/msdnmag/is...g/Default.aspx 我们的Web服务器将做什么?我们创建的简单Web服务器将接受客户端连接,读取http请求并以包含客户端请求的响应进行回复。 一旦满足请求,连接就会关闭。 Web服务器响应将以以下方式格式化:
private static readonly string responseFormat =
"HTTP/1.1 200 OK\r\n"+
"Server: XF.HTTP/0.1\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Length: {0}\r\n"+
"Connection: Close\r\n\r\n{1}";
请注意,XF.HTTP是Kodart Technologies的计划中的开源项目,如果它包含其他产品的功能而不降低性能,则可能使竞争对手落后。
实际上,本文包含XF.HTTP服务器原型的源代码,该文件由Kodart Technologies很高兴提供。
代码审查
好的,让我们返回代码。 开发XF.Server组件是为了支持服务器业务逻辑的单元测试。 这就是使用接口传递服务器和连接对象的原因,您可以轻松地对其进行模拟以测试逻辑。
internal static IServer server;
static void Main()
{
server = new Server();
StartServer();
Console.WriteLine("Web Server is Ready. Press any key to exit.");
Console.ReadKey(true);
StopServer();
}
internal static void StartServer()
{
server.OnConnect += OnClientConnect;
/* Start the server listening on port 80 */
server.Start(80);
}
internal static void StopServer()
{
server.Stop();
}
因为它只是一个演示http服务器,所以我们不希望请求超过1024个字节。
如果更长,它将被截断。
internal static void OnClientConnect(IConnection conn)
{
/* Allocate a buffer for read operation per client */
byte[] buffer = new byte[1024];
conn.ReadAsync(buffer, buffer.Length, OnReadComplete, null);
}
XF.Server中的完成例程机制有很大的优化;
如果您回想起异步网络编程模型在.NET中的工作方式,您会记住在完成例程中您将重复异步调用。
但这又将涉及许多操作,这些操作具有锁定缓冲区,获取回调委托的函数指针等。
在XF.Server中,您只是想/不想使用OperarionArgs对象中的Repeat标志重复操作。
internal static void OnReadComplete(OperationArgs args)
{
/* If the connection is not closed */
if (args.Bytes != 0)
{
string content = Encoding.ASCII.GetString(args.Buffer).Substring(0, args.Bytes);
string response = String.Format(responseFormat, content.Length, content);
args.Connection.WriteAsync(Encoding.ASCII.GetBytes(response), response.Length, OnWriteComplete, null);
args.Repeat = false;
}
}
internal static void OnWriteComplete(OperationArgs args)
{
args.Connection.Close();
}
而已。
只需几行代码,Web服务器就可以使用了。
绩效结果
我们的Web服务器应用程序和IIS / 6.0已在相同的平台(Intel Core2 Duo,2GB RAM)和Microsoft Web Application Stress Tool上进行了测试。 客户端和服务器位于使用100MB / S LAN连接的不同计算机上。
为了使性能测试公平,要求IIS / 6.0返回静态内容的短文本文件。 IIS应该缓存常用的内容,这就是为什么我们不考虑磁盘I / O开销的原因。 如果IIS不缓存,则对IIS开发人员来说是一个大问题;)
该测试已经运行了一分钟,并且收到了以下结果:
IIS/6.0 Results:
Requests/Second: 1338.14
Socket Errors
Connect:0
Send:1
Recv:3
Timeout:0
---- XF.HTTP Results:
Requests/Second: 3841.92
Socket Errors
Connect:0
Send:0
Recv:0
Timeout:0
结果非常令人惊讶。
在测试过程中,请同时检查CPU使用率,您会注意到IIS的CPU使用率不稳定,并且总是在20-80%之间跳跃。
相反,XF.HTTP的CPU使用率非常稳定,并且在70%到80%之间变化,这表示服务器设计更好。
结论不管XF.Server仍在开发中,并且仅发布了CTP,如果您正在编写服务器应用程序或要改进现有的.NET服务器应用程序,都应考虑使用它。
使用XF.Server组件和几行代码,我们设法编写了一个可以有效处理数千个并发连接的简单Web服务器。
XF.Server组件提供了前所未有的性能。 即使使用CF版本的XF.Server,所有提供300-500请求/秒的套接字组件也都远远落后。
如果您知道可以提供更好性能的组件,请发表您的问题和评论。如果您有不同的结果,请进行基准测试并在此处评论。
tcp/ip多线程通信