SocketAsyncEventArgs是.net提供的关于异步socket类,封装了IOCP的使用,可以用它方便的实现NIO(non-blocking IO)

NIO对于提升某些场景下Server性能和吞吐量有很大益处,准备在服务框架中使用它来编写简易rpc的部分

不过例子还是感觉复杂了点,我只是需要知道SocketAsyncEventArgs本身如何使用而已,于是自行简化了一下:

   1:  using System;
   2:  using System.Net;
   3:  using System.Net.Sockets;
   4:  using System.Text;
   5:   
   6:  namespace SocketAsyncServer
   7:  {
   8:      public static class Program
   9:      {
  10:          public static void Main(String[] args)
  11:          {
  12:              IPAddress[] addressList = Dns.GetHostEntry(Environment.MachineName).AddressList;
  13:              new TcpListener().Listen(new IPEndPoint(addressList[addressList.Length - 1], 9900));
  14:   
  15:              Console.ReadKey();
  16:          }
  17:      }
  18:   
  19:      public class TcpListener
  20:      {
  21:          private SocketAsyncEventArgs Args;
  22:          private Socket ListenerSocket;
  23:          private StringBuilder buffers;
  24:          public TcpListener() { }
  25:          public void Listen(EndPoint e)
  26:          {
  27:              //buffer
  28:              buffers = new StringBuilder();
  29:              //socket
  30:              ListenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  31:              ListenerSocket.Bind(e);
  32:              ListenerSocket.Listen(10);
  33:              //异步socket事件
  34:              Args = new SocketAsyncEventArgs();
  35:              Args.Completed += new EventHandler<SocketAsyncEventArgs>(ProcessAccept);
  36:              BeginAccept(Args);
  37:              Console.WriteLine("server run at {0}", e.ToString());
  38:          }
  39:   
  40:          //开始接受
  41:          void BeginAccept(SocketAsyncEventArgs e)
  42:          {
  43:              e.AcceptSocket = null;
  44:              if (!ListenerSocket.AcceptAsync(e))
  45:                  ProcessAccept(ListenerSocket, e);
  46:          }
  47:          //接受完毕 开始接收和发送
  48:          void ProcessAccept(object sender, SocketAsyncEventArgs e)
  49:          {
  50:              Socket s = e.AcceptSocket;
  51:              e.AcceptSocket = null;
  52:   
  53:              int bufferSize = 10;//1000 * 1024;
  54:              var args = new SocketAsyncEventArgs();
  55:              args.Completed += new EventHandler<SocketAsyncEventArgs>(OnIOCompleted);
  56:              args.SetBuffer(new byte[bufferSize], 0, bufferSize);
  57:              args.AcceptSocket = s;
  58:              if (!s.ReceiveAsync(args))
  59:                  this.ProcessReceive(args);
  60:   
  61:              BeginAccept(e);
  62:          }
  63:   
  64:          //IOCP回调
  65:          void OnIOCompleted(object sender, SocketAsyncEventArgs e)
  66:          {
  67:              switch (e.LastOperation)
  68:              {
  69:                  case SocketAsyncOperation.Receive:
  70:                      this.ProcessReceive(e);
  71:                      break;
  72:                  case SocketAsyncOperation.Send:
  73:                      this.ProcessSend(e);
  74:                      break;
  75:                  default:
  76:                      throw new ArgumentException("The last operation completed on the socket was not a receive or send");
  77:              }
  78:          }
  79:          
  80:          //接收完毕
  81:          void ProcessReceive(SocketAsyncEventArgs e)
  82:          {
  83:              if (e.BytesTransferred > 0)
  84:              {
  85:                  if (e.SocketError == SocketError.Success)
  86:                  {
  87:                      //读取
  88:                      var data=Encoding.ASCII.GetString(e.Buffer, e.Offset, e.BytesTransferred);
  89:                      buffers.Append(data);
  90:                      Console.WriteLine("Received:{0}", data);
  91:   
  92:                      if (e.AcceptSocket.Available == 0)
  93:                      {
  94:                          //读取完毕
  95:                          Console.WriteLine("Receive Complete.Data:{0}", buffers.ToString());
  96:                          //重置
  97:                          buffers = new StringBuilder();
  98:                          //发送反馈
  99:                          Byte[] sendBuffer = Encoding.ASCII.GetBytes("result from server");
 100:                          e.SetBuffer(sendBuffer, 0, sendBuffer.Length);
 101:                          if (!e.AcceptSocket.SendAsync(e))
 102:                          {
 103:                     
 104:                              this.ProcessSend(e);
 105:                          }
 106:                      }
 107:                      else if (!e.AcceptSocket.ReceiveAsync(e))
 108:                      {
 109:                          this.ProcessReceive(e);
 110:                      }
 111:                  }
 112:                  else
 113:                  {
 114:                      //this.ProcessError(e);
 115:                  }
 116:              }
 117:              else
 118:              {
 119:                  //this.CloseClientSocket(e);
 120:              }
 121:          }
 122:          //发送完毕
 123:          void ProcessSend(SocketAsyncEventArgs e)
 124:          {
 125:              if (e.SocketError == SocketError.Success)
 126:              {
 127:   
 128:                  if (!e.AcceptSocket.ReceiveAsync(e))
 129:                  {
 130:                      this.ProcessReceive(e);
 131:                  }
 132:              }
 133:              else
 134:              {
 135:   
 136:              }
 137:          }
 138:      }
 139:       
 140:  }

上述代码run起来之后,打开cmd用telnet测试下即可

telnet 127.0.0.1 9900

SocketAsyncEventArgs的更多相关文章

  1. 【转】C#高性能大容量SOCKET并发(二):SocketAsyncEventArgs封装

    http://blog.csdn.net/sqldebug_fan/article/details/17557341 1.SocketAsyncEventArgs介绍 SocketAsyncEvent ...

  2. 基于SocketAsyncEventArgs的版本

    文字水平差就慢慢开始练习,同时分享一下,项目中写的简单socket程序,不同方式的版本,今天上一个异步.可能实现高性能的处理方式.IOCP就不多说了,高性能的完成端口,可以实现套接字对象的复用,降低开 ...

  3. C#使用SocketAsyncEventArgs操作套接字的简单异步通讯

    SocketAsyncEventArgs是一个套接字操作的类,主要作用是实现socket消息的异步接收和发送,跟Socket的BeginSend和 BeginReceive方法异步处理没有多大区别,它 ...

  4. [转帖]译文:如何使用SocketAsyncEventArgs类(How to use the SocketAsyncEventArgs class)

    原文链接:http://norke.blog.163.com/blog/static/276572082011828104315941/ 引言 我一直在探寻一个高性能的Socket客户端代码.以前,我 ...

  5. 译文:如何使用SocketAsyncEventArgs类(How to use the SocketAsyncEventArgs class)

      转载自: http://blog.csdn.net/hulihui/article/details/3244520 原文:How to use the SocketAsyncEventArgs c ...

  6. SocketAsyncEventArgs使用解说

    原文:SocketAsyncEventArgs使用解说 如果在.NET下写过网络通讯的同学应该感觉不陌生了,有很多刚入门的同学很多都认为这东西可以大大提高处理效能还有就是使用上很不适应.其实使用之前最 ...

  7. .netcore使用SocketAsyncEventArgs Pool需要注意!

    在.net中做网络通讯往往都会用到SocketAsyncEventArgs,为了得到更好的性能配合Pool复用SocketAsyncEventArgs可以得到一个更好的效果,但在dotnet core ...

  8. (转)C#SocketAsyncEventArgs实现高效能多并发TCPSocket通信

    原文地址:http://freshflower.iteye.com/blog/2285272.http://freshflower.iteye.com/blog/2285286 一)服务器端 说到So ...

  9. SocketAsyncEventArgs的释放问题

    起因是发现一个同事编写的程序运行两个月左右,占用了服务器20G左右的内存.用WinDbg查看发现存在大量的Async Pinned Handles,而它们的gcroot都来自于SocketAsyncE ...

  10. UDP的socketasynceventargs

    C# 使用 SocketAsyncEventArgs 实现UdpSocket系列 http://www.cnblogs.com/zwq194/archive/2012/10/30/2746393.ht ...

随机推荐

  1. Linux 之 inotify+rsync 备份文件系统

    一.需求 1.线上有不同的机房,并且每个机房所对公网开放端口不一样. 2.A机房中的a机器是台文件服务器,需要备份到B机房中的b机器,以及C机房中的c机器. 3.并且保持实时同步.只要a上面的文件有改 ...

  2. hibernate操作数据库时报错解决方式

    java.sql.SQLException: Parameter index out of range (28 > number of parameters, which is 27). 这个说 ...

  3. JS控制文字只显示两行,超出部分显示省略号

    由于使用css控制文字只显示多行,超出部分显示省略号,存在一定的兼容性问题,所以总结了一下网上一些大咖使用js实现控制行数的解决方案. 第一步:依次引入jquery.js+jquery.ellipsi ...

  4. leetcode747

    public class Solution { public int DominantIndex(int[] nums) { var list = new List<KeyValuePair&l ...

  5. 转载----我与CMDB不得不说的故事

    每次读到配置管理相关的书籍时,我总在想:“这些定义很精准,流程也很完整,但这不是真正的难题.”对于一个配置管理者来说,真正的难题不是绘制“庞大而精美”的数据模型,不是设计“全天候.无死角”的管控流程, ...

  6. 判断字符串为空 为null

    str:string; delphi str.IsNullOrEmpty str.IsNullOrWhiteSpace TStringHelper for delphi only,c++ no use ...

  7. Spring与Redis的实现

    前言 Redis作为缓存还是相当不错的,一定程度上缓解了数据库的IO操作,具体不多说,具体网上查找资料. 实战 不多说,直接上代码. 第一步:所需要的依赖 <!-- redis --> & ...

  8. Set与List之间转化

    List list = new ArrayList(set);Set set = new HashSet(list); //但是有一点,转换当中可能要丢失数据,尤其是从list转换到set的时候,因为 ...

  9. win 10+ iis 10 部署.net core 1.1 web api

    今天上午部署了wcf,部署了好久,一直没有部署好,最后找到了dudu的部署方法,结果中午吃饭的时候成功了,这是链接:http://www.cnblogs.com/dudu/p/3328066.html ...

  10. NormalMapping

    [NormalMapping] 法线贴图内的数据是法线,高度贴图内的数据是高度,不是一个东西.在ShaderLab中,UnpackNormal()分析的是法线贴图(注意不是高度贴图). 可以看到,在G ...