在 .NET Framework 2.0 版本中,System.Net.Sockets 命名空间提供了一个几乎拥有 Windows® WinSock Win32® API 的所有功能的 Socket 类。该功能所属的类包含为托管代码开发人员设计的各种方法和属性。在 Socket 上,有一组包括 Send 和 Receive 在内的同步方法,具备针对各种情况的参数重载。这些同步方法不仅易于使用,而且非常适合于使用套接字的简单网络任务。Socket 上还有一组基于异步编程模型 (APM) 的异步方法,APM 在 .NET Framework 中非常普遍(有关详细信息,请参阅 msdn.microsoft.com/msdnmag/issues/07/03/ConcurrentAffairs)。这些异步方法让 Socket 类的异步使用相对简单,而且还提供了一种方法来处理许多套接字,或处理在许多套接字上进行的多个发送和接收操作。

2.0 版本的 Socket 类适合多种需要使用网络套接字的客户端应用程序,以及一些服务器和服务类型的应用程序。遗憾的是,一些服务应用程序方案不适用于 2.0 版本的 Socket 类,却和直接使用 Windows WinSock API 的本机语言相容。2.0 版本的 Socket 类的主要问题是它不仅在分配必要的基础对象以便在大量套接字上同时保持 I/O 操作时需要占用过多的 CPU 循环,而且在执行单个套接字 I/O 操作时也同样如此。

凭借 .NET Framework 3.5,公共语言运行时 (CLR) 便可以更有效地同时管理大量的 Overlapped 对象。CLR 中的 Overlapped 对象可以有效封装用于管理异步 I/O 操作的本机 Windows OVERLAPPED 结构。每个进行中的 Socket 异步 I/O 操作中都有一个 Overlapped 对象实例。现在可以拥有 6 万个甚至更多的连接套接字,并同时在每个套接字上保持一个挂起的异步接收 I/O 操作。

2.0 版本的 Socket 类使用 Windows I/O 完成端口来完成异步 I/O 操作。这使应用程序可以轻易地扩展到大量的打开的套接字。.NET Framework 实现了 System.Threading.ThreadPool 类,该类提供可读取完成端口并完成异步 I/O 操作的完成线程。在开发即将发布的 3.5 版本的 .NET Framework 的过程中,我们将大量的精力放在了消除代码路径中的开销上,包括读取完成端口和调用应用程序的完成代理或在 IAsyncResult 对象中发出 I/O 完成事件对象信号之间。

.NET Framework 中的 APM 也称为 Begin/End 模式。这是因为会调用 Begin 方法来启动异步操作,然后返回一个 IAsyncResult 对象。可以选择将一个代理作为参数提供给 Begin 方法,异步操作完成时会调用该方法。或者,一个线程可以等待 IAsyncResult.AsyncWaitHandle。当回调被调用或发出等待信号时,就会调用 End 方法来获取异步操作的结果。这种模式很灵活,使用相对简单,在 .NET Framework 中非常常见。

但是,您必须注意,如果进行大量异步套接字操作,是要付出代价的。针对每次操作,都必须创建一个 IAsyncResult 对象,而且该对象不能被重复使用。由于大量使用对象分配和垃圾收集,这会影响性能。为了解决这个问题,新版本提供了另一个使用套接字上执行异步 I/O 的方法模式。这种新模式并不要求为每个套接字操作分配操作上下文对象。

我们没有创建全新的模式,而只是采用现有模式并做了一个基本更改。现在,在 Socket 类中有了一些方法,它们使用基于事件的完成模型的变体。在 2.0 版本中,您可以使用下列代码在某个套接字上启动异步发送操作:

void OnSendCompletion(IAsyncResult ar) { }
IAsyncResult ar = socket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, OnSendCompletion, state);

在新版本中,您还可以实现:

void OnSendCompletion(object src, SocketAsyncEventArgs sae) { }
SocketAsyncEventArgs sae = new SocketAsyncEventArgs();
            sae.Completed += OnSendCompletion;
            sae.SetBuffer(buffer, 0, buffer.Length);
socket.SendAsync(sae);

这里有一些明显的差别。封装操作上下文的是一个 SocketAsyncEventArgs 对象,而不是 IAsyncResult 对象。该应用程序创建并管理(甚至可以重复使用)SocketAsyncEventArgs 对象。套接字操作的所有参数都由 SocketAsyncEventArgs 对象的属性和方法指定。完成状态也由 SocketAsyncEventArgs 对象的属性提供。最后,需要使用事件处理程序回调完成方法。

所有这些更改都显著改进了 .NET Framework 3.5 中 System.Net.Sockets 类的性能和可伸缩性。现有应用程序可以自动实现其中的两项改进。第三项改进,即新型 Socket 方法,只能通过修改应用程序而得到使用,但这些方法都能为基于套接字的高要求应用程序提供更理想的可伸缩性。

一个Tcp版的EchoServer的示例如下:

class EchoServer
    {
        Socket server;

public EchoServer(IPEndPoint localPoint)
        {
            server = new Socket(localPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

server.Bind(localPoint);
            server.Listen(5);

accept_async();
        }

private void accept_async()
        {
            var accept = new SocketAsyncEventArgs();
            accept.Completed += accept_Completed;
            server.AcceptAsync(accept);
        }

void accept_Completed(object sender, SocketAsyncEventArgs e)
        {
            accept_async();

var client = e.AcceptSocket;
            
            e.Completed -= accept_Completed;
            e.Completed += receive_Completed;

var buffer = new byte[1024];
            e.SetBuffer(buffer, 0, buffer.Length);

client.ReceiveAsync(e);
        }

void receive_Completed(object sender, SocketAsyncEventArgs e)
        {
            var client = sender as Socket;
            if (e.BytesTransferred == 0)
            {
                Console.WriteLine("socket is closed");
                client.Close();
            }
            else
            {
                client.Send(e.Buffer, e.BytesTransferred, SocketFlags.None);

client.ReceiveAsync(e);
            }
        }
    }

原文链接:http://www.csharpwin.com/csharpspace/2243.shtml

作者:天方

.NET 3.5 Socket APM相关推荐

  1. ELK入门(十八)——Kibana APM server安装部署

    一.前言 安装内容: elasticsearch-7.10.1-linux-x86_64.tar.gz(依赖,注意版本) kibana-7.10.1-linux-x86_64.tar.gz(依赖,注意 ...

  2. linux常用c函数(中文版)

    都是linux的c函数东西略多,用页面搜索来查找吧. << Back to man.ChinaUnix.net isalnum(测试字符是否为英文或数字) 相关函数 isalpha,isd ...

  3. 百度前200页部分答案(初稿)

    1操作系统中 heap 和 stack 的区别 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.Java自动管理栈和堆,程序员不能直接地设置栈或堆. 在函数中定义的一些基本类 ...

  4. .NET3.5中的高性能 Socket API

    在 .NET Framework 2.0 版本中,System.Net.Sockets 命名空间提供了一个几乎拥有 Windows® WinSock Win32® API 的所有功能的 Socket ...

  5. 异步tcp通信——APM.Core 服务端概述

    为什么使用异步 异步线程是由线程池负责管理,而多线程,我们可以自己控制,当然在多线程中我们也可以使用线程池.就拿网络扒虫而言,如果使用异步模式去实现,它使用线程池进行管理.异步操作执行时,会将操作丢给 ...

  6. C# 线程知识--异步编程模型(APM)

    在构建高性能.可伸缩的应用程序时,必定会采用异步操作来提升应用程序性能,改善用户体验,异步操作与线程池结合允许使用很少的线程执行许多的操作.CLR中提供了一种异步操作的模式即异步编程模式. 1.异步编 ...

  7. 【Socket】苍老师有了丈夫,我也有了SAEA

    一.前言        时间过得真是快,转眼就2018年了.首先祝各位博友,软件开发者新年新气象,事业有成,身体健康,阖家幸福!最近看到园子里好多关于自己的2017年度总结以及对自己新一年的愿景,觉得 ...

  8. APM和Mission Planner间使用4G GPRS通信

    这样就实现的数传的4G通信 因为我国不允许移动端开启socket服务,所以我使用的是, APM和MP分别连接到服务器,数据包在服务器做左右手交换, 另外APM使用  "4G DTU透传模块 ...

  9. 干货 | 携程无线APM升级实践

    作者简介 辛贵,携程无线研发总监.主要负责App基础框架研发相关工作,关注App开发框架.性能.质量.效率和新技术. 1.背景介绍 APM全称为Application Performance Mana ...

  10. 带你打造一套APM系统

    APM 是 Application Performance Monitoring 的缩写,监视和管理软件应用程序的性能和可用性.应用性能管理对一个应用的持续稳定运行至关重要.所以这篇文章就从一个 iO ...

最新文章

  1. DRBD数据同步部署-centos7
  2. 微信小程序 textarea 简易解决方案
  3. idea用token登陆github_用python和她一起唐诗宋词
  4. C++中cstring和int互换
  5. Postman: Test
  6. 计算机网络---分层结构、协议、接口、服务
  7. 解决输出顺时针螺旋数组问题【寻路算法】
  8. 【matlab】syms x y 用法
  9. Eclipse ADT 更换主题
  10. C#开发ActiveX控件
  11. 1.4.4 Performance Measures
  12. {转]太经典了,我不得不收藏
  13. spring-boot2 + vue2+element-ui + avue + uni-app (兮家开源商城)
  14. 计算机病毒的常用方法,常用计算机检测病毒的方法
  15. 串口通信协议---UART
  16. 小米电视怎么看cctv?安装小鲸电视免广告教程值得看
  17. xp计算机u盘重装系统,处理a豆电脑u盘重装系统xp步骤
  18. 迟到的2016年年终总结----拒绝平庸的一年
  19. 2016届阿里实习生java研发岗一面二面三面四面经验分享
  20. TreeMap和LinkedHashMap

热门文章

  1. 认识以及安装redis
  2. linux学习第四课:命令格式和目录处理命令
  3. ELK之LogStacs
  4. Sublime Text3 插件:convertToUTF8
  5. Android心得1.5--第一次搭建Android环境的心得和第一个应用程序部分代码解析
  6. Swift实现LRU缓存淘汰算法
  7. 你不主动去要世界也不会给你 漫话开源项目的可持续发展之路
  8. crontab 定时执行任务
  9. 快速入门分布式消息队列之 RabbitMQ(2)
  10. 51nod 1060 最复杂的数