C 货币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其实只要用到Socket联接,基本上就得使用Thread,是交叉使用的。C#封装的Socket用法基本上不算很复杂,只是不知道托管之后的Socket有没有其他性能或者安全上的问题。在C#里面能找到的最底层的操作也就是socket了,概念不做解释。程序模型如下:WinForm程序 : 启动端口侦听;监视Socket联接情况;定期关闭不活动的联接;Listener:处理Socket的Accept函数,侦听新链接,建立新Thread来处理这些联接(Connection)。Connection:处理具体的每一个联接的会话。 1:WinForm如何启动一个新的线程来启动Listener://start the serverprivate void btn_startServer_Click(object sender, EventArgs e){//this.btn_startServer.Enabled = false;Thread _createServer = new Thread(new ThreadStart(WaitForConnect));_createServer.Start();}//wait all connectionsprivate void WaitForConnect(){SocketListener listener = new SocketListener(Convert.ToInt32(this.txt_port.Text));listener.StartListening();}因为侦听联接是一个循环等待的函数,所以不可能在WinForm的线程里面直接执行,不然Winform也就是无法继续任何操作了,所以才指定一个新的线程来执行这个函数,启动侦听循环。这一个新的线程是比较简单的,基本上没有启动的参数,直接指定处理函数就可以了。2:Listener如何启动循环侦听,并且启动新的带有参数的线程来处理Socket联接会话。先看如何建立侦听:(StartListening函数)IPEndPoint localEndPoint = new IPEndPoint(_ipAddress, _port);// Create a TCP/IP socket. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// Bind the socket to the local endpoint and listen for incoming connections. try{listener.Bind(localEndPoint);listener.Listen(20);//20 trucks // Start listening for connections. while (true){// here will be suspended while waiting for a new connection. Socket connection = listener.Accept();Logger.Log("Connect", connection.RemoteEndPoint.ToString());//log it, new connection……}}……基本步骤比较简单:建立本机的IPEndPoint对象,表示以本机为服务器,在指定端口侦听;然后绑定到一个侦听Socket上;进入while循环,等待新的联接;如果有新的联接,那么建立新的socket来对应这个联接的会话。值得注意的就是这一句联接代码:listener.Accept()。执行这一句的时候,程序就在这个地方等待,直到有新的联检请求的时候程序才会执行下一句。这是同步执行,当然也可以异步执行。 新的联接Socket建立了(Accept之后),对于这些新的socket该怎么办呢?他们依然是一个循环等待,所以依然需要建立新的Thread给这些Socket去处理会话(接收/发送消息),而这个Thread就要接收参数了。Thread本身是不能接收参数的,为了让它可以接收参数,可以采用定义新类,添加参数作为属性的方法来解决。因为每一个Socket是一个Connection周期,所以我定义了这么一个类public class Connection。这个类至少有这样一个构造函数public Connection(Socket socket); 之所以这么做,就是为了把Socket参数传给这个Connection对象,然后好让Listener启动这个Thread的时候,Thread可以知道他正在处理哪一个Socket。具体处理的方法:(在Listener的StartListening函数,ocket connection […]
View Details