SocketAsyncEventArgs
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的更多相关文章
- 【转】C#高性能大容量SOCKET并发(二):SocketAsyncEventArgs封装
http://blog.csdn.net/sqldebug_fan/article/details/17557341 1.SocketAsyncEventArgs介绍 SocketAsyncEvent ...
- 基于SocketAsyncEventArgs的版本
文字水平差就慢慢开始练习,同时分享一下,项目中写的简单socket程序,不同方式的版本,今天上一个异步.可能实现高性能的处理方式.IOCP就不多说了,高性能的完成端口,可以实现套接字对象的复用,降低开 ...
- C#使用SocketAsyncEventArgs操作套接字的简单异步通讯
SocketAsyncEventArgs是一个套接字操作的类,主要作用是实现socket消息的异步接收和发送,跟Socket的BeginSend和 BeginReceive方法异步处理没有多大区别,它 ...
- [转帖]译文:如何使用SocketAsyncEventArgs类(How to use the SocketAsyncEventArgs class)
原文链接:http://norke.blog.163.com/blog/static/276572082011828104315941/ 引言 我一直在探寻一个高性能的Socket客户端代码.以前,我 ...
- 译文:如何使用SocketAsyncEventArgs类(How to use the SocketAsyncEventArgs class)
转载自: http://blog.csdn.net/hulihui/article/details/3244520 原文:How to use the SocketAsyncEventArgs c ...
- SocketAsyncEventArgs使用解说
原文:SocketAsyncEventArgs使用解说 如果在.NET下写过网络通讯的同学应该感觉不陌生了,有很多刚入门的同学很多都认为这东西可以大大提高处理效能还有就是使用上很不适应.其实使用之前最 ...
- .netcore使用SocketAsyncEventArgs Pool需要注意!
在.net中做网络通讯往往都会用到SocketAsyncEventArgs,为了得到更好的性能配合Pool复用SocketAsyncEventArgs可以得到一个更好的效果,但在dotnet core ...
- (转)C#SocketAsyncEventArgs实现高效能多并发TCPSocket通信
原文地址:http://freshflower.iteye.com/blog/2285272.http://freshflower.iteye.com/blog/2285286 一)服务器端 说到So ...
- SocketAsyncEventArgs的释放问题
起因是发现一个同事编写的程序运行两个月左右,占用了服务器20G左右的内存.用WinDbg查看发现存在大量的Async Pinned Handles,而它们的gcroot都来自于SocketAsyncE ...
- UDP的socketasynceventargs
C# 使用 SocketAsyncEventArgs 实现UdpSocket系列 http://www.cnblogs.com/zwq194/archive/2012/10/30/2746393.ht ...
随机推荐
- OD 实验(六) - 对一个程序的破解
程序: 双击进行安装,安装过程默认就好了 安装完成 运行程序 输入 User 为 sch01ar,点击 Create 点击 Log In 这里显示为未注册版本 看看未注册版本有哪些功能被限制 这里会显 ...
- PHP redis client封装
config1.inc.php if (!isset($_REQUEST['pageName']) || $_REQUEST['pageName'] != 'txl-app-test') { $CON ...
- github上的版本发布
当前的版本号 发布版本 比如 git tag -a v1. 把这个版本发布到线上 git push --tags
- vue组件之echarts报表
vue组件之echarts报表 将echarts报表封装成组件,动态传入数据,显示图表. 1.饼状图 父组件: <MPie :datas="piedata"></ ...
- 「小程序JAVA实战」小程序模块之间引用(19)
转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-19/ 上一节,讲了页面引用模块的概念,如果是模块之前引用呢?源码:https://github.c ...
- JAVA实现汉字转换为拼音 pinyin4j/JPinyin
在项目中经常会遇到需求用户输入汉字后转换为拼音的场景,比如说通讯录,就会要求按名字首字符发音排序,如果自己写实现这方面的功能是个很好大的工程,还好网上有公开的第三方jar支持转换,结合网上很多前辈的代 ...
- 【开发工具】Jenkins+Gitlab实现自动化部署
我在尝试在容器中安装Jenkins时,初衷是希望使用docker in docker 的模式来实现Jenkins slave容器按需创建.在实现的时候需要在Jenkins 中安装Kubernetes插 ...
- VS2013 查看程序各个函数的CPU利用率<转>
自己写的程序CPU占用率过高,无法锁定原因时,可以用VS2013帮忙检测 1. 打开VS 性能分析 2. 启动项目进行检测 3. 选择CPU采样 完成 4. 分析一段时间 然后停止分析 5. 选择显示 ...
- 基于 DirectX11 的 MMDViewer 02-创建一个窗口
项目的创建和配置: 1.新建一个 Win32 空项目 2.创建源码文件夹.库文件夹和资源文件夹 3.在 VS2013(我使用的 IDE 是 vs2013)配置这些文件夹 这里使用了 $(Solutio ...
- 实现把C语言编译成java字节码的编译器 一个将C语言编译成java字节码的实例