C# 集合类 Array Arraylist List Hashtable Dictionary Stack Queue 1.数组是固定大小的,不能伸缩。虽然System.Array.Resize这个泛型方法可以重置数组大小, 但是该方法是重新创建新设置大小的数组,用的是旧数组的元素初始化。随后以前的数组就废弃!而集合却是可变长的 2.数组要声明元素的类型,集合类的元素类型却是object. 3.数组可读可写不能声明只读数组。集合类可以提供ReadOnly方法以只读方式使用集合。 4.数组要有整数下标才能访问特定的元素,然而很多时候这样的下标并不是很有用。集合也是数据列表却不使用下标访问。 很多时候集合有定制的下标类型,对于队列和栈根本就不支持下标访问! //数组 int[] intArray1; //初始化已声明的一维数组 intArray1 = new int[3]; intArray1 = new int[3]{1,2,3}; intArray1 = new int[]{1,2,3}; //ArrayList类对象被设计成为一个动态数组类型,其容量会随着需要而适当的扩充 方法 1:Add()向数组中添加一个元素, 2:Remove()删除数组中的一个元素 3:RemoveAt(int i)删除数组中索引值为i的元素 4:Reverse()反转数组的元素 5:Sort()以从小到大的顺序排列数组的元素 6:Clone()复制一个数组 //List 可通过索引访问的对象的强类型列表。提供用于对列表进行搜索、排序和操作的方法 在决定使用 List 还是使用 ArrayList 类(两者具有类似的功能)时,记住 List 类在大多数情况下执行得更好并且是类型安全的。如果对 List 类的类型 T 使用引用类型,则 两个类的行为是完全相同的。但是,如果对类型 T 使用值类型,则需要考虑实现和装箱问题。 如果对类型 T 使用值类型,则编译器将特别针对该值类型生成 List 类的实现。这意味着不必对 List 对象的列表元素进行装箱就可以使用该元素,并且在创建大约 500 个列表 元素之后,不对列表元素装箱所节省的内存将大于生成该类实现所使用的内存。 //Dictionary 表示键和值的集合。Dictionary遍历输出的顺序,就是加入的顺序,这点与Hashtable不同 //SortedList类 与哈希表类似,区别在于SortedList中的Key数组排好序的 //Hashtable类 哈希表,名-值对。类似于字典(比数组更强大)。哈希表是经过优化的,访问下标的对象先散列过。如果以任意类型键值访问其中元素会快于其他集合。 GetHashCode()方法返回一个int型数据,使用这个键的值生成该int型数据。哈希表获取这个值最后返回一个索引,表示带有给定散列的数据项在字典中存储的位置。 //Stack类 栈,后进先出。push方法入栈,pop方法出栈。 Queue类 队列,先进先出。enqueue方法入队列,dequeue方法出队列。 ————————————————————- //Dictionary System.Collections.DictionaryEntry dic=new System.Collections.DictionaryEntry("key1","value1"); Dictionary<int, string> fruit = new Dictionary<int, […]
View DetailsC 货币2.5.ToString("C")¥2.50 D 十进制数25.ToString("D5")00025E 科学型25000.ToString("E")2.500000E+005F 固定点25.ToString("F2")25.00G 常规2.5.ToString("G")2.5 N 数字2500000.ToString("N")2,500,000.00X 十六进制255.ToString("X")FF formatCode 是可选的格式化代码字符串。(详细内容请搜索“格式化字符串”查看) 必须用“{”和“}”将格式与其他字符分开。如果恰好在格式中也要使用大括号,可以用连续的两个大括号表示一个大括号,即: “{{”或者“}}”。常用格式举例:(1) int i=12345;this.textBox1.Text=i.ToString();//结果 12345(this指当前对象,或叫当前类的实例)this.textBox2.Text=i.ToString("d8");//结果 00012345(2) int i=123;double j=123.45;string s1=string.Format("the value is {0,7}",i);string s2=string.Format("the value is {0,73}",j);this.textBox1.Text=s1 ;//结果 the value is 123this.textBox2.Text=s2;//结果 the value is 123.450(3)double i=12345.6789;this.textBox1.Text=i.ToString("f2"); //结果 12345.68this.textBox2.Text=i.ToString("f6");//结果 12345.678900(4)double i=12345.6789;this.textBox1.Text=i.ToString("n"); //结果 12,345.68this.textBox2.Text=i.ToString(“n4”); //结果 12,345.6789(5)double i=0.126;string s=string.Format("the value is {0:p}",i);this.textBox1.Text=i.ToString("p"); //结果 12.6%this.textBox2.Text=s; //结果 the value is 12.6%(6) DateTime dt =new DateTime(2003,5,25);this.textBox1.Text=dt.ToString("yy.M.d");//结果 03.5.25this.textBox2.Text=dt.ToString(“yyyy年M月”);//结果 2003年5月Convert.ToDateTime("2005/12/22 22:22:22").ToString("yyyy/MM/dd HHss")"2005/12/22 22:22:22"(7) int i=123;double j=123.45;string s=string.Format("i:{0,-7},j:{1,7}",i,j);//-7表示左对齐,占7位this.textBox1.Text=s ;//结果i:123 ,j: 123.45 DateTime.ToString()用法详解我们经常会遇到对时间进行转换,达到不同的显示效果,默认格式为:2006-6-6 14:33:34 如果要换成成200606,06-2006,2006-6-6或更多的格式该怎么办呢?这里将要用到DateTime.ToString的方法(String, IFormatProvider)示例:using System;using System.Globalization;String format="D";DateTime date=DataTime.Now;Response.Write(date.ToString(format, DateTimeFormatInfo.InvariantInfo));结果输出Thursday, June 16, 2006在这里列出了参数format格式详细用法=======================格式字符 关联属性/说明 […]
View Details由于之前一阵公司一个项目提出的需求,自己也想进行这方面的尝试,我对如何使用 Flash 来做 WinForm 程序的界面产生了兴趣,于是学习了一些资料,摘要于此。 要在 WinForm 中使用 Flash,通常需要用到 Shockwave Flash Object 这个 COM 组件。 具体步骤如下: 首先添加对 COM 组件 Shockwave Flash Object 的引用,将该组件拖到窗体上之后,可以设置如下关键属性: Movie: Flash 的存放地址 EmbedMovie: 是否嵌入到程序的资源中。 接下来你可以设置其他一些属性,使得 Flash 的窗口最大化,隐藏掉其宿主程序的 C# WinForm 窗体。 在 Flash 的 ActionScript 中,可以通过 FSCommand 函数与 hosting app 通信,该函数有两个参数,分别是: command: 命令名称 parameters: 参数 例子: on(press){ fscommand("Circule", "Green"); } 在 C# 中,处理 Flash 对象的 FSCommand 事件即可。 如果该事件处理函数的 EventArgs 为 e, 则有如下对应关系: e.command -> Flash 中调用 FSCommand 时的 command 参数; e.args -> Flash 中调用 FSCommand 时的 arguments 参数。 在 C# 中往 Flash 传递数值用 SetVariable 方法: […]
View Details1、在.net中,windows服务的实现类必需继承于System.ServiceProcess.ServiceBase public partial class myService : ServiceBase { } 2、在windows服务的实现类的构造函数中进行必要的初始化工作,如设置系统标识服务的简短名称等。 public partial class myService : ServiceBase { public SqlBackupService() { ServiceName = "Myservice"; AutoLog = false; CanStop = true; } } 3、重写OnStar和OnStop函数,在OnStar里实现具体功能,OnStop中释放OnStat中创建的资源。 public partial class myService : ServiceBase { private int tickcount = 0; private System.Timers.Timer t = null; public SqlBackupService() { ServiceName = "Myservice"; AutoLog = false; CanStop = true; } protected override void OnStart(string[] args) { Console.WriteLine("Myservice start …"); //建立定时器 t = new System.Timers.Timer(10000); t.AutoReset = true; //每隔10000毫秒触发一次 t.Elapsed += new System.Timers.ElapsedEventHandler(myWork); t.Start(); […]
View Details_ _ DbType 说明 OleDbType 说明 SqlDbType 说明 Boolean 简单类型,表示 true 或 false 的布尔值。 Boolean 布尔值 (DBTYPE_BOOL)。它映射到 Boolean。 Bit Boolean。无符号数值,可以是 0、1 或 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing)。 SByte 整型,表示值介于 -128 到 127 之间的有符号 8 位整数。 TinyInt 8 位带符号的整数 (DBTYPE_I1)。它映射到 SByte。 Byte 一个 8 位无符号整数,范围在 0 到 255 之间。 UnsignedTinyInt 8 位无符号整数 (DBTYPE_UI1)。它映射到 Byte。 TinyInt Byte。8 位的无符号整数。 Int16 整型,表示值介于 -32768 到 32767 之间的有符号 16 位整数。 SmallInt 16 位带符号的整数 (DBTYPE_I2)。它映射到 Int16。 SmallInt Int16。16 位的有符号整数。 Int32 整型,表示值介于 -2147483648 到 2147483647 之间的有符号 […]
View Details
1 |
<ol class="dp-c"><li class="alt"><span><span>1.通过HttpWebResponse 来获取 </span></span></li><li><span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">string</span><span> CheckTeamSiteUrl(</span><span class="keyword">string</span><span> url) </span></span></li><li class="alt"><span> { </span></li><li><span> <span class="keyword">string</span><span> response = </span><span class="string">""</span><span>; </span></span></li><li class="alt"><span> HttpWebResponse httpResponse = <span class="keyword">null</span><span>; </span></span></li><li><span> </span></li><li class="alt"><span> <span class="comment">//assert: user have access to URL </span><span> </span></span></li><li><span> <span class="keyword">try</span><span> </span></span></li><li class="alt"><span> { </span></li><li><span> HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url); </span></li><li class="alt"><span> httpRequest.Headers.Set(<span class="string">"Pragma"</span><span>, </span><span class="string">"no-cache"</span><span>); </span></span></li><li><span> </span></li><li class="alt"><span> <span class="comment">// request.Headers.Set("KeepAlive", "true"); </span><span> </span></span></li><li><span> </span></li><li class="alt"><span> httpRequest.CookieContainer = <span class="keyword">new</span><span> CookieContainer(); </span></span></li><li><span> </span></li><li class="alt"><span> </span></li><li><span> </span></li><li class="alt"><span> httpRequest.Referer = url; </span></li><li><span> </span></li><li class="alt"><span> httpRequest.UserAgent = <span class="string">"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"</span><span>; </span></span></li><li><span> </span></li><li class="alt"><span> </span></li><li><span> </span></li><li class="alt"><span> httpRequest.Credentials = System.Net.CredentialCache.DefaultCredentials; </span></li><li><span> httpResponse = (HttpWebResponse)httpRequest.GetResponse(); </span></li><li class="alt"><span> </span></li><li><span> } </span></li><li class="alt"><span> <span class="keyword">catch</span><span> (Exception ex) </span></span></li><li><span> { </span></li><li class="alt"><span> <span class="keyword">throw</span><span> </span><span class="keyword">new</span><span> ApplicationException(</span><span class="string">"HTTP 403 Access denied, URL: "</span><span> + url, ex); </span></span></li><li><span> } </span></li><li class="alt"><span> </span></li><li><span> <span class="comment">//if here, the URL is correct and the user has access </span><span> </span></span></li><li class="alt"><span> <span class="keyword">try</span><span> </span></span></li><li><span> { </span></li><li class="alt"><span> <span class="keyword">string</span><span> strEncod = httpResponse.ContentType; </span></span></li><li><span> StreamReader stream; </span></li><li class="alt"><span> <span class="keyword">if</span><span> (strEncod.ToLower().IndexOf(</span><span class="string">"utf"</span><span>) != -1) </span></span></li><li><span> { </span></li><li class="alt"><span> stream = <span class="keyword">new</span><span> StreamReader(httpResponse.GetResponseStream(), System.Text.Encoding.UTF8); </span></span></li><li><span> } </span></li><li class="alt"><span> <span class="keyword">else</span><span> </span></span></li><li><span> { </span></li><li class="alt"><span> stream = <span class="keyword">new</span><span> StreamReader(httpResponse.GetResponseStream(), System.Text.Encoding.Default); </span></span></li><li><span> } </span></li><li class="alt"><span> </span></li><li><span> <span class="keyword">char</span><span>[] buff = </span><span class="keyword">new</span><span> </span><span class="keyword">char</span><span>[4000]; </span></span></li><li class="alt"><span> stream.ReadBlock(buff,0,4000); </span></li><li><span> response = <span class="keyword">new</span><span> </span><span class="keyword">string</span><span>(buff); </span></span></li><li class="alt"><span> stream.Close(); </span></li><li><span> httpResponse.Close(); </span></li><li class="alt"><span> } </span></li><li><span> <span class="keyword">catch</span><span> (Exception ex) </span></span></li><li class="alt"><span> { </span></li><li><span> <span class="keyword">throw</span><span> </span><span class="keyword">new</span><span> ApplicationException(</span><span class="string">"HTTP 404 Page not found, URL: "</span><span> + url, ex); </span></span></li><li class="alt"><span> } </span></li><li><span> <span class="keyword">return</span><span> response; </span></span></li><li class="alt"><span> </span></li><li><span> } </span></li><li class="alt"><span> </span></li><li> </li><li><span>2.通过 WebResponse 来获取 </span></li><li class="alt"><span> <span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">string</span><span> getPage(String url) </span></span></li><li><span> { </span></li><li class="alt"><span> WebResponse result = <span class="keyword">null</span><span>; </span></span></li><li><span> <span class="keyword">string</span><span> resultstring = </span><span class="string">""</span><span>; </span></span></li><li class="alt"><span> <span class="keyword">try</span><span> </span></span></li><li><span> { </span></li><li class="alt"><span> WebRequest req = WebRequest.Create(url); </span></li><li><span> req.Timeout = 30000; </span></li><li class="alt"><span> result = req.GetResponse(); </span></li><li><span> Stream ReceiveStream = result.GetResponseStream(); </span></li><li class="alt"><span> </span></li><li><span> <span class="comment">//read the stream into a string </span><span> </span></span></li><li class="alt"><span> <span class="comment">//StreamReader sr = new StreamReader(ReceiveStream, System.Text.Encoding.UTF8); </span><span> </span></span></li><li><span> <span class="keyword">string</span><span> strEncod = result.ContentType; </span></span></li><li class="alt"><span> StreamReader sr; </span></li><li><span> <span class="keyword">if</span><span> (strEncod.ToLower().IndexOf(</span><span class="string">"utf"</span><span>) != -1) </span></span></li><li class="alt"><span> { </span></li><li><span> sr = <span class="keyword">new</span><span> StreamReader(ReceiveStream, System.Text.Encoding.UTF8); </span></span></li><li class="alt"><span> } </span></li><li><span> <span class="keyword">else</span><span> </span></span></li><li class="alt"><span> { </span></li><li><span> sr = <span class="keyword">new</span><span> StreamReader(ReceiveStream, System.Text.Encoding.Default); </span></span></li><li class="alt"><span> } </span></li><li><span> resultstring = sr.ReadToEnd(); </span></li><li class="alt"><span> js.alert(resultstring); </span></li><li><span> <span class="comment">//Console.WriteLine(resultstring); </span><span> </span></span></li><li class="alt"><span> } </span></li><li><span> <span class="keyword">catch</span><span> </span></span></li><li class="alt"><span> { </span></li><li><span> <span class="keyword">throw</span><span> </span><span class="keyword">new</span><span> Exception(); </span></span></li><li class="alt"><span> } </span></li><li><span> <span class="keyword">finally</span><span> </span></span></li><li class="alt"><span> { </span></li><li><span> <span class="keyword">if</span><span> (result != </span><span class="keyword">null</span><span>) </span></span></li><li class="alt"><span> { </span></li><li><span> result.Close(); </span></li><li class="alt"><span> } </span></li><li><span> } </span></li><li class="alt"><span> <span class="keyword">return</span><span> resultstring; </span></span></li><li><span> } </span></li><li class="alt"><span> </span></li><li> </li><li><span>3.通过WebClient来获取 </span></li><li class="alt"><span> <span class="keyword">public</span><span> </span><span class="keyword">string</span><span> </span><span class="keyword">get</span><span>(</span><span class="keyword">int</span><span> length) </span></span></li><li><span> { </span></li><li class="alt"><span> <span class="keyword">try</span><span> </span></span></li><li><span> { </span></li><li class="alt"><span> getEncodeing(); </span></li><li><span> WebClient wb = <span class="keyword">new</span><span> WebClient(); </span></span></li><li class="alt"><span> Stream response = wb.OpenRead(url); </span></li><li><span> StreamReader reader = <span class="keyword">new</span><span> StreamReader(response, </span><span class="keyword">this</span><span>.encoding, </span><span class="keyword">true</span><span>, 256000); </span></span></li><li class="alt"><span> <span class="keyword">char</span><span>[] a = </span><span class="keyword">new</span><span> </span><span class="keyword">char</span><span>[length]; </span></span></li><li><span> <span class="keyword">int</span><span> i = reader.Read(a,0,length); </span></span></li><li class="alt"><span> reader.Close(); </span></li><li><span> <span class="keyword">return</span><span> </span><span class="keyword">new</span><span> </span><span class="keyword">string</span><span>(a); </span></span></li><li class="alt"><span> } </span></li><li><span> <span class="keyword">catch</span><span> (Exception e) </span></span></li><li class="alt"><span> { </span></li><li><span> <span class="keyword">return</span><span> e.Message; </span></span></li><li class="alt"><span> <span class="comment">//return null; </span><span> </span></span></li><li><span> } </span></li><li class="alt"><span> } </span></li><li><span> <span class="keyword">private</span><span> </span><span class="keyword">void</span><span> getEncodeing() </span></span></li><li class="alt"><span> { </span></li><li><span> <span class="keyword">switch</span><span> (</span><span class="keyword">this</span><span>.encode) </span></span></li><li class="alt"><span> { </span></li><li><span> <span class="keyword">case</span><span> </span><span class="string">"UTF-8"</span><span>: encoding = Encoding.UTF8; </span><span class="keyword">break</span><span>; </span></span></li><li class="alt"><span> <span class="keyword">case</span><span> </span><span class="string">"GB2312"</span><span>: encoding = Encoding.GetEncoding(</span><span class="string">"GB2312"</span><span>); </span><span class="keyword">break</span><span>; </span></span></li><li><span> <span class="keyword">case</span><span> </span><span class="string">"ASCII"</span><span>: encoding = Encoding.ASCII; </span><span class="keyword">break</span><span>; </span></span></li><li class="alt"><span> <span class="keyword">default</span><span>: encoding = Encoding.GetEncoding(encode); </span><span class="keyword">break</span><span>; </span></span></li><li><span> } </span></li><li class="alt"><span> } </span></li></ol> |
FROM http://blog.sina.com.cn/s/blog_758087190100rfri.html
View Details<add key="MySqlString" value="server=localhost;port=3306;user id=userid;password=123456;database=dbname;CharSet=utf8;Allow Zero Datetime=true"/>
View Detailspublic string Hello{ Response.Write("test"); Response.End9() } 客户端:2 1 using System; 2 using System.Net; 3 using System.Net.Sockets; 4 using System.Text; 5 6 public class SynchronousSocketClient { 7 8 public static void StartClient() { 9 // Data buffer for incoming data. 10 byte[] bytes = new byte[1024]; 11 12 // Connect to a remote device. 13 try { 14 // Establish the remote endpoint for the socket. 15 // This example uses port 11000 on the local computer. 16 IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()) 17 IPAddress ipAddress = ipHostInfo.AddressList[0]; 18 IPEndPoint remoteEP = […]
View Details/// <summary>/// 十进制转换为二进制/// </summary>/// <param name="x"></param>/// <returns></returns> public static string DecToBin(string x){string z = null;int X = Convert.ToInt32(x);int i = 0;long a, b = 0;while (X > 0){a = X%2;X = X/2;b = b + a*Pow(10, i);i++;}z = Convert.ToString(b);return z;} /// <summary>/// 16进制转ASCII码/// </summary>/// <param name="hexString"></param>/// <returns></returns> public static string HexToAscii(string hexString){StringBuilder sb = new StringBuilder();for (int i = 0; i <= hexString.Length – 2; i += 2){sb.Append(Convert.ToString(Convert.ToChar(Int32.Parse(hexString.Substring(i, 2),System.Globalization.NumberStyles.HexNumber))));}return sb.ToString();} /// <summary>/// 十进制转换为八进制/// </summary>/// <param name="x"></param>/// <returns></returns> public static string DecToOtc(string x){string z = null;int X = Convert.ToInt32(x);int […]
View Details最近浏览了几篇有关Socket发送消息的文章,发现大家对Socket Send方法理解有所偏差,现将自己在开发过程中对Socket的领悟写出来,以供大家参考。 (一)架构 基于TCP协议的Socket通信,架构类似于B/S架构,一个Socket通信服务器,多个Socket通信客户端。Socket通信服务器启动时,会建立一个侦听Socket,侦听Socket将侦听到的Socket连接传给接受Socket,然后由接受Socket完成接受、发送消息,当Socket存在异常时,断开连接。在实际开发项目中,往往要求Socket通信服务器能提供高效、稳定的服务,一般会用到以下技术:双工通信、完成端口、SAEA、池、多线程、异步等。特别是池,用的比较多,池一般包括一下几种: 1)Buffer池,用于集中管控Socket缓冲区,防止内存碎片。 2)SAEA池,用于集中管控Socket,重复利用Socket。 3)SQL池,用于分离网络服务层与数据访问层(SQL的执行效率远远低于网络层执行效率)。 4)线程池,用于从线程池中调用空闲线程执行业务逻辑,进一步提高网络层运行效率。 (二)Send 主服务器接受Socket为一端口,客户端Socket为一端口,这两个端口通过TCP协议建立连接,通信基础系统负责管理此连接,它有两个功能: 1)发送消息 2)接受消息 Socket的Send方法,并非大家想象中的从一个端口发送消息到另一个端口,它仅仅是拷贝数据到基础系统的发送缓冲区,然后由基础系统将发送缓冲区的数据到连接的另一端口。值得一说的是,这里的拷贝数据与异步发送消息的拷贝是不一样的,同步发送的拷贝,是直接拷贝数据到基础系统缓冲区,拷贝完成后返回,在拷贝的过程中,执行线程会IO等待, 此种拷贝与Socket自带的Buffer空间无关,但异步发送消息的拷贝,是将Socket自带的Buffer空间内的所有数据,拷贝到基础系统发送缓冲区,并立即返回,执行线程无需IO等待,所以异步发送在发送前必须执行SetBuffer方法,拷贝完成后,会触发你自定义回调函数ProcessSend,在ProcessSend方法中,调用SetBuffer方法,重新初始化Buffer空间。 口说无凭,下面给个例子: 服务器端: 客户端: 解释: 客户端第一次发送数据:1234567890。 客户端第一个接受数据:1234567890,该数据由服务端用Send同步方法发送返回。 客户端第二个接受数据:1234567890,该数据由服务端用Send异步方法发送返回。 以上似乎没什么异常,好,接下来,我只发送abc。 客户端第一个接受数据:abc,理所当然,没什么问题。 客户端第二个接受数据:abc4567890!为什么呢?应该是abc才对呀! 好,现在为大家解释一下: 异步发送是将其Buffer空间中所有数据拷贝到基础系统发送缓冲区,第一次拷贝1234567890到发送缓冲区,所以收到1234567890,第二次拷贝abc到发送缓冲区,替换了先前的123,所以收到abc4567890,大家明白的? 源码: BufferManager
1 |
<div><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Collections.Generic;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Net.Sockets;<br /><br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> This class creates a single large buffer which can be divided up <br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> and assigned to SocketAsyncEventArgs objects for use with each <br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> socket I/O operation. <br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> This enables bufffers to be easily reused and guards against <br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> fragmenting heap memory.<br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> <br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> The operations exposed on the BufferManager class are not thread safe.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> BufferManager<br />{<br /> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> m_numBytes; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> the total number of bytes controlled by the buffer pool</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">byte</span><span style="color: rgb(0, 0, 0);">[] m_buffer; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> the underlying byte array maintained by the Buffer Manager</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> Stack</span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> m_freeIndexPool; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> </span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> m_currentIndex;<br /> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> m_bufferSize;<br /><br /> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> BufferManager(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> totalBytes, </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> bufferSize)<br /> {<br /> m_numBytes </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> totalBytes;<br /> m_currentIndex </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">0</span><span style="color: rgb(0, 0, 0);">;<br /> m_bufferSize </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> bufferSize;<br /> m_freeIndexPool </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Stack</span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);">();<br /> }<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Allocates buffer space used by the buffer pool</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> InitBuffer()<br /> {<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> create one big large buffer and divide that <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> out to each SocketAsyncEventArg object</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> m_buffer </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">byte</span><span style="color: rgb(0, 0, 0);">[m_numBytes];<br /> }<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Assigns a buffer from the buffer pool to the <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> specified SocketAsyncEventArgs object<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> <returns>true if the buffer was successfully set, else false</returns></span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> SetBuffer(SocketAsyncEventArgs args)<br /> {<br /><br /> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (m_freeIndexPool.Count </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">0</span><span style="color: rgb(0, 0, 0);">)<br /> {<br /> args.SetBuffer(m_buffer, m_freeIndexPool.Pop(), m_bufferSize);<br /> }<br /> </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"><br /> {<br /> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> ((m_numBytes </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> m_bufferSize) </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);"> m_currentIndex)<br /> {<br /> </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">;<br /> }<br /> args.SetBuffer(m_buffer, m_currentIndex, m_bufferSize);<br /> m_currentIndex </span><span style="color: rgb(0, 0, 0);">+=</span><span style="color: rgb(0, 0, 0);"> m_bufferSize;<br /> }<br /> </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">;<br /> }<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Removes the buffer from a SocketAsyncEventArg object. <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> This frees the buffer back to the buffer pool</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> FreeBuffer(SocketAsyncEventArgs args)<br /> {<br /> m_freeIndexPool.Push(args.Offset);<br /> args.SetBuffer(</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(128, 0, 128);">0</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(128, 0, 128);">0</span><span style="color: rgb(0, 0, 0);">);<br /> }<br /><br />}<br /></span></div> |
SocketAsyncEventArgsPool
1 |
<div><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Collections.Generic;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Net.Sockets;<br /><br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Represents a collection of reusable SocketAsyncEventArgs objects. </span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> SocketAsyncEventArgsPool<br />{<br /> Stack</span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">SocketAsyncEventArgs</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> m_pool;<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Initializes the object pool to the specified size<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> The "capacity" parameter is the maximum number of <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> SocketAsyncEventArgs objects the pool can hold</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> SocketAsyncEventArgsPool(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> capacity)<br /> {<br /> m_pool </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Stack</span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">SocketAsyncEventArgs</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);">(capacity);<br /> }<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Add a SocketAsyncEventArg instance to the pool<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">The "item" parameter is the SocketAsyncEventArgs instance <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> to add to the pool</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Push(SocketAsyncEventArgs item)<br /> {<br /> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (item </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) { </span><span style="color: rgb(0, 0, 255);">throw</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> ArgumentNullException(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Items added to a SocketAsyncEventArgsPool cannot be null</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">); }<br /> </span><span style="color: rgb(0, 0, 255);">lock</span><span style="color: rgb(0, 0, 0);"> (m_pool)<br /> {<br /> m_pool.Push(item);<br /> }<br /> }<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Removes a SocketAsyncEventArgs instance from the pool<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> and returns the object removed from the pool</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> SocketAsyncEventArgs Pop()<br /> {<br /> </span><span style="color: rgb(0, 0, 255);">lock</span><span style="color: rgb(0, 0, 0);"> (m_pool)<br /> {<br /> </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> m_pool.Pop();<br /> }<br /> }<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> The number of SocketAsyncEventArgs instances in the pool</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> Count<br /> {<br /> </span><span style="color: rgb(0, 0, 255);">get</span><span style="color: rgb(0, 0, 0);"> { </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> m_pool.Count; }<br /> }<br /><br />}</span></div> |
1 |
<div><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Collections.Generic;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Linq;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Text;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Net.Sockets;<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> AsyncUserToken<br />{<br /> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> Socket Socket;<br />}<br /></span></div> |
Server
1 |
<div><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Threading;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Net.Sockets;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Net;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Text;<br /><br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Implements the connection logic for the socket server. <br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> After accepting a connection, all data read from the client <br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> is sent back to the client. The read and echo back to the client pattern <br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> is continued until the client disconnects.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Server<br />{<br /> </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> m_numConnections; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> the maximum number of connections the sample is designed to handle simultaneously </span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> m_receiveBufferSize;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> buffer size to use for each socket I/O operation </span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> BufferManager m_bufferManager; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> represents a large reusable set of buffers for all socket operations</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> opsToPreAlloc </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">2</span><span style="color: rgb(0, 0, 0);">; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> read, write (don't alloc buffer space for accepts)</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> Socket listenSocket; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> the socket used to listen for incoming connection requests<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> pool of reusable SocketAsyncEventArgs objects for write, read and accept socket operations</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> SocketAsyncEventArgsPool m_readWritePool;<br /> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> m_totalBytesRead; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> counter of the total # bytes received by the server</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> m_numConnectedSockets; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> the total number of clients connected to the server </span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> Semaphore m_maxNumberAcceptedClients;<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Create an uninitialized server instance. <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> To start the server listening for connection requests<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> call the Init method followed by Start method <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> <param name="numConnections">the maximum number of connections the sample is designed to handle simultaneously</param><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> <param name="receiveBufferSize">buffer size to use for each socket I/O operation</param></span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> Server(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> numConnections, </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> receiveBufferSize)<br /> {<br /> m_totalBytesRead </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">0</span><span style="color: rgb(0, 0, 0);">;<br /> m_numConnectedSockets </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">0</span><span style="color: rgb(0, 0, 0);">;<br /> m_numConnections </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> numConnections;<br /> m_receiveBufferSize </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> receiveBufferSize;<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> allocate buffers such that the maximum number of sockets can have one outstanding read and <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">write posted to the socket simultaneously </span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> m_bufferManager </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> BufferManager(receiveBufferSize </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> numConnections </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> opsToPreAlloc,<br /> receiveBufferSize);<br /><br /> m_readWritePool </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> SocketAsyncEventArgsPool(numConnections);<br /> m_maxNumberAcceptedClients </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Semaphore(numConnections, numConnections);<br /> }<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Initializes the server by preallocating reusable buffers and <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> context objects. These objects do not need to be preallocated <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> or reused, but it is done this way to illustrate how the API can <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> easily be used to create reusable objects to increase server performance.<br /> </span><span style="color: rgb(0, 128, 0);">//<br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Init()<br /> {<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Allocates one large byte buffer which all I/O operations use a piece of. This gaurds <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> against memory fragmentation</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> m_bufferManager.InitBuffer();<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> preallocate pool of SocketAsyncEventArgs objects</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> SocketAsyncEventArgs readWriteEventArg;<br /><br /> </span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">0</span><span style="color: rgb(0, 0, 0);">; i </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);"> m_numConnections; i</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">)<br /> {<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">Pre-allocate a set of reusable SocketAsyncEventArgs</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> readWriteEventArg </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> SocketAsyncEventArgs();<br /> readWriteEventArg.Completed </span><span style="color: rgb(0, 0, 0);">+=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> EventHandler</span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">SocketAsyncEventArgs</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);">(IO_Completed);<br /> readWriteEventArg.UserToken </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> AsyncUserToken();<br /> <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> assign a byte buffer from the buffer pool to the SocketAsyncEventArg object</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> m_bufferManager.SetBuffer(readWriteEventArg);<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> add SocketAsyncEventArg to the pool</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> m_readWritePool.Push(readWriteEventArg);<br /> }<br /><br /> }<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Starts the server such that it is listening for <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> incoming connection requests. <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> <param name="localEndPoint">The endpoint which the server will listening <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> for connection requests on</param></span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Start(IPEndPoint localEndPoint)<br /> {<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> create the socket which listens for incoming connections</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> listenSocket </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);<br /> listenSocket.Bind(localEndPoint);<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> start the server with a listen backlog of 100 connections</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> listenSocket.Listen(</span><span style="color: rgb(128, 0, 128);">100</span><span style="color: rgb(0, 0, 0);">);<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> post accepts on the listening socket</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> StartAccept(</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">);<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">Console.WriteLine("{0} connected sockets with one outstanding receive posted to each....press any key", m_outstandingReadCount);</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> Console.WriteLine(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Press any key to terminate the server process....</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /> Console.ReadKey();<br /> }<br /><br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Begins an operation to accept a connection request from the client <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> <param name="acceptEventArg">The context object to use when issuing <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> the accept operation on the server's listening socket</param></span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> StartAccept(SocketAsyncEventArgs acceptEventArg)<br /> {<br /> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (acceptEventArg </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">)<br /> {<br /> acceptEventArg </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> SocketAsyncEventArgs();<br /> acceptEventArg.Completed </span><span style="color: rgb(0, 0, 0);">+=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> EventHandler</span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">SocketAsyncEventArgs</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);">(AcceptEventArg_Completed);<br /> }<br /> </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"><br /> {<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> socket must be cleared since the context object is being reused</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> acceptEventArg.AcceptSocket </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br /> }<br /><br /> m_maxNumberAcceptedClients.WaitOne();<br /> </span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> willRaiseEvent </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> listenSocket.AcceptAsync(acceptEventArg);<br /> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">willRaiseEvent)<br /> {<br /> ProcessAccept(acceptEventArg);<br /> }<br /> }<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> This method is the callback method associated with Socket.AcceptAsync <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> operations and is invoked when an accept operation is complete<br /> </span><span style="color: rgb(0, 128, 0);">//<br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> AcceptEventArg_Completed(</span><span style="color: rgb(0, 0, 255);">object</span><span style="color: rgb(0, 0, 0);"> sender, SocketAsyncEventArgs e)<br /> {<br /> ProcessAccept(e);<br /> }<br /><br /> </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> ProcessAccept(SocketAsyncEventArgs e)<br /> {<br /> Interlocked.Increment(</span><span style="color: rgb(0, 0, 255);">ref</span><span style="color: rgb(0, 0, 0);"> m_numConnectedSockets);<br /> Console.WriteLine(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">Client connection accepted. There are {0} clients connected to the server</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,<br /> m_numConnectedSockets);<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Get the socket for the accepted client connection and put it into the <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">ReadEventArg object user token</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> SocketAsyncEventArgs readEventArgs </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> m_readWritePool.Pop();<br /> ((AsyncUserToken)readEventArgs.UserToken).Socket </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> e.AcceptSocket;<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> As soon as the client is connected, post a receive to the connection</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> willRaiseEvent </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> e.AcceptSocket.ReceiveAsync(readEventArgs);<br /> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">willRaiseEvent)<br /> {<br /> ProcessReceive(readEventArgs);<br /> }<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Accept the next connection request</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> StartAccept(e);<br /> }<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> This method is called whenever a receive or send operation is completed on a socket <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> <param name="e">SocketAsyncEventArg associated with the completed receive operation</param></span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> IO_Completed(</span><span style="color: rgb(0, 0, 255);">object</span><span style="color: rgb(0, 0, 0);"> sender, SocketAsyncEventArgs e)<br /> {<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> determine which type of operation just completed and call the associated handler</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">switch</span><span style="color: rgb(0, 0, 0);"> (e.LastOperation)<br /> {<br /> </span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);"> SocketAsyncOperation.Receive:<br /> ProcessReceive(e);<br /> </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br /> </span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);"> SocketAsyncOperation.Send:<br /> ProcessSend(e);<br /> </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br /> </span><span style="color: rgb(0, 0, 255);">default</span><span style="color: rgb(0, 0, 0);">:<br /> </span><span style="color: rgb(0, 0, 255);">throw</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> ArgumentException(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">The last operation completed on the socket was not a receive or send</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /> }<br /><br /> }<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> This method is invoked when an asynchronous receive operation completes. <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> If the remote host closed the connection, then the socket is closed. <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> If data was received then the data is echoed back to the client.<br /> </span><span style="color: rgb(0, 128, 0);">//<br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> ProcessReceive(SocketAsyncEventArgs e)<br /> {<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> check if the remote host closed the connection</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> AsyncUserToken token </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (AsyncUserToken)e.UserToken;<br /> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (e.BytesTransferred </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">0</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&&</span><span style="color: rgb(0, 0, 0);"> e.SocketError </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> SocketError.Success)<br /> {<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">increment the count of the total bytes receive by the server</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> Interlocked.Add(</span><span style="color: rgb(0, 0, 255);">ref</span><span style="color: rgb(0, 0, 0);"> m_totalBytesRead, e.BytesTransferred);<br /> Console.WriteLine(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">The server has read a total of {0} bytes</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, m_totalBytesRead);<br /><br /><br /> Int32 BytesToProcess </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> e.BytesTransferred;<br /> Byte[] bt </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Byte[BytesToProcess];<br /> Buffer.BlockCopy(e.Buffer, e.Offset, bt, </span><span style="color: rgb(128, 0, 128);">0</span><span style="color: rgb(0, 0, 0);">, BytesToProcess);<br /> </span><span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);"> strReceive </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Encoding.Default.GetString(bt);<br /><br /><br /> Send(token.Socket, bt, </span><span style="color: rgb(128, 0, 128);">0</span><span style="color: rgb(0, 0, 0);">, bt.Length, </span><span style="color: rgb(128, 0, 128);">1000</span><span style="color: rgb(0, 0, 0);">);<br /><br /><br /> Thread.Sleep(</span><span style="color: rgb(128, 0, 128);">1000</span><span style="color: rgb(0, 0, 0);">);<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">echo the data received back to the client<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">e.SetBuffer(e.Offset, e.BytesTransferred);</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> willRaiseEvent </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> token.Socket.SendAsync(e);<br /> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">willRaiseEvent)<br /> {<br /> ProcessSend(e);<br /> }<br /><br /> }<br /> </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"><br /> {<br /> CloseClientSocket(e);<br /> }<br /> }<br /><br /><br /> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Send(Socket socket, </span><span style="color: rgb(0, 0, 255);">byte</span><span style="color: rgb(0, 0, 0);">[] buffer, </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> offset, </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> size, </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> timeout)<br /> {<br /> socket.SendTimeout </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">0</span><span style="color: rgb(0, 0, 0);">;<br /> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> startTickCount </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Environment.TickCount;<br /> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> sent </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">0</span><span style="color: rgb(0, 0, 0);">; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> how many bytes is already sent</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">do</span><span style="color: rgb(0, 0, 0);"><br /> {<br /> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (Environment.TickCount </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> startTickCount </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> timeout)<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">throw new Exception("Timeout.");</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"><br /> {<br /> sent </span><span style="color: rgb(0, 0, 0);">+=</span><span style="color: rgb(0, 0, 0);"> socket.Send(buffer, offset </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> sent, size </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> sent, SocketFlags.None);<br /> }<br /> </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (SocketException ex)<br /> {<br /> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (ex.SocketErrorCode </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> SocketError.WouldBlock </span><span style="color: rgb(0, 0, 0);">||</span><span style="color: rgb(0, 0, 0);"><br /> ex.SocketErrorCode </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> SocketError.IOPending </span><span style="color: rgb(0, 0, 0);">||</span><span style="color: rgb(0, 0, 0);"><br /> ex.SocketErrorCode </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> SocketError.NoBufferSpaceAvailable)<br /> {<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> socket buffer is probably full, wait and try again</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> Thread.Sleep(</span><span style="color: rgb(128, 0, 128);">30</span><span style="color: rgb(0, 0, 0);">);<br /> }<br /> </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 0, 255);">throw</span><span style="color: rgb(0, 0, 0);"> ex; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> any serious error occurr</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> }<br /> } </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);"> (sent </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);"> size);<br /> }<br /><br /><br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> This method is invoked when an asynchronous send operation completes. <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> The method issues another receive on the socket to read any additional <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> data sent from the client<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> <param name="e"></param></span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> ProcessSend(SocketAsyncEventArgs e)<br /> {<br /> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (e.SocketError </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> SocketError.Success)<br /> {<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">e.SetBuffer(e.Offset, 10);<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> done echoing data back to the client</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> AsyncUserToken token </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (AsyncUserToken)e.UserToken;<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> read the next block of data send from the client</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> willRaiseEvent </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> token.Socket.ReceiveAsync(e);<br /> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">willRaiseEvent)<br /> {<br /> ProcessReceive(e);<br /> }<br /> }<br /> </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"><br /> {<br /> CloseClientSocket(e);<br /> }<br /> }<br /><br /> </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> CloseClientSocket(SocketAsyncEventArgs e)<br /> {<br /> AsyncUserToken token </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> e.UserToken </span><span style="color: rgb(0, 0, 255);">as</span><span style="color: rgb(0, 0, 0);"> AsyncUserToken;<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> close the socket associated with the client</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"><br /> {<br /> token.Socket.Shutdown(SocketShutdown.Send);<br /> }<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> throws if client process has already closed</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Exception) { }<br /> token.Socket.Close();<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> decrement the counter keeping track of the total number of clients connected to the server</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> Interlocked.Decrement(</span><span style="color: rgb(0, 0, 255);">ref</span><span style="color: rgb(0, 0, 0);"> m_numConnectedSockets);<br /> m_maxNumberAcceptedClients.Release();<br /> Console.WriteLine(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">A client has been disconnected from the server. There are {0} clients connected to the server</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, m_numConnectedSockets);<br /><br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Free the SocketAsyncEventArg so they can be reused by another client</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"> m_readWritePool.Push(e);<br /> }<br /><br />}</span></div> |
Program
1 |
<div><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Net;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Collections.Generic;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.IO;<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Program<br />{<br /> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Main(</span><span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);">[] args)<br /> {<br /> IPEndPoint iep </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> IPEndPoint(IPAddress.Parse(</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(128, 0, 0);">10.1.20.6</span><span style="color: rgb(128, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">), </span><span style="color: rgb(128, 0, 128);">1333</span><span style="color: rgb(0, 0, 0);">);<br /><br /> Server objServer </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Server(</span><span style="color: rgb(128, 0, 128);">1000</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(128, 0, 128);">10</span><span style="color: rgb(0, 0, 0);">);<br /> objServer.Init();<br /> objServer.Start(iep);<br /> }<br />}<br /></span></div> |
http://www.cnblogs.com/tianzhiliang/archive/2010/09/08/1821623.html
View Details