sqlserver占用CPU达到100%原因
CPU占用率高的原因 CPU占用率高是对物理硬盘的查询次数多;内存使用率高是物理磁盘—虚拟内存—内存三种之间数据交换次数多。 防杀毒软件造成故障或病毒、木马造成,特别是蠕虫病毒在系统内部或网络内部迅速复制,造成CPU占用资源率居高不下; 驱动没有经过认证或某些软件与系统不兼容,造成CPU资源占用100%; 服务器硬件问题:磁盘、内存/虚拟内存等等; 网络问题:网络带宽被大量占用,造成可用带宽较少,从而影响速度; 数据库设计的问题:触发器造成死锁、作业多且频繁、中间表的大量使用、游标的大量使用、索引的设计不合理、事务操作频繁; SQL语句设计不合理,造成查询效率低下、影响服务器性能的发挥; 二 CPU占用率高解决方法 针对上述原因及可能,有以下处理: 杀毒软件升级,对服务器系统和所在的局域网进行全面、严格的杀毒; 对服务器上已经安装的软件进行考证、整理,不装没有认证的驱动、尽量装兼容性强的必需软件、去掉不必需的软件;对服务器系统、端口进行监控,定时清理系统垃圾文件、关闭不使用和高危险端口; 定期周期性检查服务器硬件问题、整理系统磁盘,使服务器性能得到最大程度发挥;制定《电脑使用规范》,规范中明确使用范围和禁止范围,并依据规范定期查询各个部门的电脑使用情况;对网络结构、交换机定期检查、维护和调整;升级硬件; 使用sql server自带的性能分析追踪工具sql profiler分析数据库设计所产生问题的来源,进行有针对性处理; 使用sql server自带的查询性能分析工具sql query analyzer对可能影响性能且使用频繁的查询语句进行优化; 或升级sql server;重装sql server或服务器操作系统;使用cpu降温软件等辅助软件。 如果这些还解决不了问题的话,那就比较麻烦,需要专业人士对网站进行整体优化,更改错误不合理的程序,优化后cpu占用能降至百分之十左右 from url:http://www.e-digitalwave.com/faqview.asp?id=140
View Detailswin2003 sqlserver cpu 100%
郁闷,过年放假回来第二天,公司服务器scsi硬盘放屁啦,幸好数据库和图片昨天都备过份,但恢复的东东也让我头疼啊iis,sqlserver,生成100w的静态页,静态页我没备,55555555555 现上北京买个块硬盘来,原来系统是windows2000,手到也没有2000啦,从网上当了个win2003就装上啦,本以为会好用点,结果出了 很多小问题,我改,最头痛的问题让我遇上啦 cpu占用率100%,网站根本就打不开啦,恢复的前几天一直正常,过了10来天突然出现这个问题,把IIS站建了几个缓冲池,设置过期时间,不管用,重 建索引不用,sqlserver分给他1g多内存一开机就吃没啦,重起N便系统不管用,在网上搜了半天,也没什么实质性的解决方法,最后终于让我搜着一个 解决方法目前还管用 @echo off echo 正在清除服务器垃圾文件,请稍等…… del /f /s /q %systemdrive%/*.tmp del /f /s /q %systemdrive%/*._mp del /f /s /q %systemdrive%/*.log del /f /s /q %systemdrive%/*.gid del /f /s /q %systemdrive%/*.chk del /f /s /q %systemdrive%/*.old del /f /s /q %systemdrive%/recycled/*.* del /f /s /q %windir%/*.bak del /f /s /q %windir%/prefetch/*.* rd /s /q %windir%/temp & md %windir%/temp del /f /q %userprofile%/cookies/*.* del /f /q %userprofile%/recent/*.* del /f /s /q "%userprofile%/Local Settings/Temporary Internet Files/*.*" del /f /s /q "%userprofile%/Local Settings/Temp/*.*" del /f […]
View Detailswindows 2003服务器优化设置
一、优化启动设置 1.禁用关机事件跟踪开始-运行-gpedit.msc-计算机配置-管理模板-系统-显示关机事件跟踪-禁用。 2. 禁用开机 CTRL+ALT+DEL和实现自动登陆方法1:打开注册表:HKEY_LOCAL_MACHIN|SOFTWARE|MicroSoft|Windows NT|CurrentVersion |Winlogon段,在此项按右键,新建二个字符串值,AutoAdminLogon=1, DefaultPassword=“为超级用户Administrator所设置的Password”。 注意,一定要为Administrator设置一个密码,否则不能实现自启动。 然后,重新启?疻indows即可实现自动登录。 方法2:管理工具-本地安全策略-本地策略-安全选项-interactive logon: Do not require CTRL+ALT+DEL,启用之。 方法3(自动登陆):使用Windows XP的Tweak UI来实现Server 2003自动登陆。下载weak UI http://www.ssite.org/uppic/sun_pic/…003/tweakui.exe下载后直接执行weakui.exe 在左边的面板中选择Logon-Autologon-在右边勾写),点击下面set Password,输入用户名的密码,然后点击OK。 3.我的电脑-属性-高级-启动和故障修复,点错误报告,选择“禁用错误汇报、但在发生严重错误时通知我”; 4.去掉将事件写入系统日志、发送管理警报、自动重新启动等选项,将写入调试信息设置为无; 5.点击编辑,在弹出记事本文件中: [Operating Systems] timeout=30 //把缺省时间 30 秒改为 0 秒 multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows server 2003rofessional" /fastdetect //把缺省 fastdetect 改为 nodetect 二、关闭华医生Dr.Watson 在开始-运行中输入“drwtsn32”,或者开始-程序-附件-系统工具-系统信息-工具-Dr Watson,调出系统里的华医生Dr.Watson ,只保留“转储全部线程上下文”选项,否则一旦程序出错,硬盘会读很久,并占用大量空间。如果以前有此情况,请查找user.dmp文件,删除后可节省几十MB空间。 三、用SFC命令释放更多空间 若确认系统不会新加设备,可把\windows\system\dellcache目录内的文件予以删除,以释放空间。 删除全部文件的命令是sfc.exe/purgecache,约300MB,本操作有危险性,对系统不熟悉者勿用。 四、视觉效果 1.我的电脑-属性-高级-性能-设置-视觉效果,选择“调整为最佳性能”; 2.我的电脑-属性-高级-性能-设置-高级,在处理器计划选择程序,内存使用选程序,这样系统会给前台程序更多资源,使之运行更快; 3.虚拟内存中点更改,256M以下内存将虚拟内存值设为物理内存的1.5倍,将初始大小和最大值设为一样,将虚拟内存设置在系统盘外。比如你的内存是256M,你可以设置为384,操作系统安装在C盘,设置内存在E盘或F盘,先点C,再点无分页文件,然后点设置,接着点E,自定义大小,更改后点“设置”才能生效。 4.打开注册表,HKEY_CURRENT_USER\Control Panel\Desktop分支,在右边窗口双击键值名MenuShowDelay,这一项的取值范围是0~100000(单位为毫秒),将默认的值改为0。 五、删除一些可不用的东西 1.删除驱动器备份 \windows\Driver cache\i386下的Driver.cab文件,约70MB。 2.删除帮助文件 \Windows\Help下,约40MB 3.删除备用DLL文件 \Windows\System32\Dllcache,约200MB.最好有安装光盘或安装文件备份,以备用。 4.删除不用的输入法 Windows\Ime,如日文,韩文,繁体中文输入法。 5.将C:\windows\temp中的文件全部删除。 六、关闭部分功能 1.关闭系统还原功能 我的电脑-属性-系统还原,选在所有的驱动器上关闭系统还原。也可关闭不重要的分区的系统还原,如果考虑系统安全,则不要关闭还原功能。 2.关闭自动更新 我的电脑-属性-自动更新,选择关闭自动更新,我将手动更新计算机。 3.关闭远程桌面 我的电脑-属性-远程,远程桌面里的允许用户远程连接到这台计算机勾去掉。 4.取消休眠功能 右键桌面-属性-屏幕保护程序-电源-休眠,将启用休眠前的勾去掉,约200MB。 七、其它优化设置 1. 将我的文档转到其他分区 在桌面的“我的文档”图标上右击鼠标,选择属性-移动,目标为F:\我的文档。 2. 将IE临时文件夹转到其他分区。 3.在任务栏中点击鼠标右键,选择属性,任务栏标签中去掉分组相似任务栏按钮前的勾。 4查看驱动器组件信息 右键我的电脑-管理存储-可移动存储-库,用右键点击所要查询的驱动器-属性-设备信息就可看到驱动器的信息了,将多余的用户名删除。 八、设置硬盘工作模式 我的电脑-属性-硬件-设备管理器-IDE […]
View Details让局域网内的XP访问win7共享文件的简易方法
局域网共享的四个因素: 一、用户权限 二、安全设置 三、同一网段(也就是同一网关) 四、必须在同一个工作组。 家里两台电脑,一台装XP,一台装win7,路由器局域网连接,以前一直是将两台机子改一致的工作组名称其它按默认,win7就能访问xp上的共享文件,但XP却不能访问win7。 查找原因发现win7默认Guest(来宾账号)是禁止的,需要手动打开: *开启Guest账号:右击我的电脑\管理\用户有个Guest,双击之去掉“账户已停用”前面的勾。 *删除“拒绝从网络上访问这台计算机”项中的guest账户:运行组策略(gpedit.msc)\本地计算机\计算机配置\windows设置\安全设置\本地策略\用户权利指派\拒绝从网络访问这台计算机。选中guest,则将其删除。(win7默认guest是不允许访问共享的) *禁用“帐户:使用空白密码的本地帐户只允许进行控制台登录” 注:有些杀毒软件的更新也会禁用来宾账号,遇到这种情况,除了查看以上的三点操作,还要: *运行服务策略“Services.msc”。启动其中的“Clipbook Server”(文件夹服务器):这个服务允许你们网络上的其他用户看到你的文件夹。当然有时你可把它改为手动启动,然后再使用其他程序在你的网络上发布信息。 <div class=’XbU3HE6′>一起讨论PHP最新技术教程学习等为主的源代码开发技术网站div> *如果无法启动Clipbook服务。错误1068:依存服务或组无法启动。需要这样的步骤(你可以看他们的依存关系):首先开启 Network DDE DSDM (如果已开启,进入第二步),其次开启 Network DDE,然后开启 Clipbook。 最后,设置win7文件共享,将需要共享的文件夹添加Guest(来宾账号)权限即可。\拒绝从网络访问这台计算机。选中guest,则将其删除。(win7默认guest是不允许访问共享的) *禁用“帐户:使用空白密码的本地帐户只允许进行控制台登录” 注:有些杀毒软件的更新也会禁用来宾账号,遇到这种情况,除了查看以上的三点操作,还要: *运行服务策略“Services.msc”。启动其中的“Clipbook Server”(文件夹服务器):这个服务允许你们网络上的其他用户看到你的文件夹。当然有时你可把它改为手动启动,然后再使用其他程序在你的网络上发布信息。 *如果无法启动Clipbook服务。错误1068:依存服务或组无法启动。需要这样的步骤(你可以看他们的依存关系):首先开启 Network DDE DSDM (如果已开启,进入第二步),其次开启 Network DDE,然后开启 Clipbook。 最后,设置win7文件共享,将需要共享的文件夹添加Guest(来宾账号)权限即可。 局域网共享的四个因素: 一、用户权限 二、安全设置 三、同一网段(也就是你们的网关) 四、必须在同一个工作组。 我下午也是因为一次杀毒软件的更新导致win7机子莫名不能访问xp的里共享文件夹。 <div class=’XbU3HE6′><发表于php中国 http://www.phpcn.cc/ >div> 按以下几条去检查应该能解决,我已解决: 1. 安装NWlink IPX/SPX/NetBIOS Compatible Transport Protocol协议。(如没安装就安装一下吧) 2. 开启Guest账号:右击我的电脑\管理\用户有个Guest,双击之去掉“账户已停用”前面的勾。 3. 右击我的电脑\属性\计算机名,查看该选项卡中出现的局域网工作组名称名称一致 4. 使用winxp防火墙的例外:winxp防火墙在默认状态下是全面启用的,这意味着运行计算机的所有网络连接,难于实现网上邻居共享。同时,由于windows防火墙默认状态下是禁止“文件与打印机共享的”,所以,启用了防火墙,往往不能共享打印,解决办法是:进入“本地连接”窗口,点“高级”\“设置”\“例外”\在程序与服务下勾选“文件和打印机共享”。 5. 删除“拒绝从网络上访问这台计算机”项中的guest账户:运行组策略(gpedit.msc)\本地计算机\计算机配置\windows设置\安全设置\本地策略\用户权利指派\拒绝从网络访问这台计算机。如果其中有guest,则将其删除。(原因是:有时xp的guest是不允许访问共享的) 禁用“帐户:使用空白密码的本地帐户只允许进行控制台登录” 6. 取消“使用简单文件共享”方式:资源管理器\工具 --文件夹选项FONT face=Times New Roman>\查看\去掉“使用简单文件共享(推荐)”前面的勾。 一起讨论PHP最新技术教程学习等为主的源代码开发技术网站 7. 检查注册表:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa右边窗口RestrictAnonymous的值是否为0。(默认是0,你可跳过去。如果不行在回到这里;如没有这一项,不管它。) 8. 勾选“本地连接\属性\Microsoft网络的文件和打印机共享”。 9. 运行服务策略“Services.msc”。启动其中的“Clipbook Server”(文件夹服务器):这个服务允许你们网络上的其他用户看到你的文件夹。当然有时你可把它改为手动启动,然后再使用其他程序在你的网络上发布信息。 10. 无法启动Clipbook服务。错误1068:依存服务或组无法启动。需要这样的步骤(你可以看他们的依存关系):首先开启 Network DDE DSDM (如果已开启,进入第二步),其次开启 Network DDE,然后开启 Clipbook。 win7和xp都按以上10条去检查一遍,基本上满足了前面说的四项共享因素条件。 我期初用IP地址可以打开其它机子的共享,点网络里的机子图标无法访问;然后来用了IPBook(超级网络邻居)工具,不觉中就好了。 […]
View Details.net连接MYSQL字符串
<add key="MySqlString" value="server=localhost;port=3306;user id=userid;password=123456;database=dbname;CharSet=utf8;Allow Zero Datetime=true"/>
View DetailsC# Socket实例
public 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 Detailsc#进制转换
/// <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深入探析c# Socket
最近浏览了几篇有关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 DetailsC#的Socket程序(TCP)
其实只要用到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 DetailsTCP与UDP区别
TCP与UDP区别 TCP—传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。 UDP—用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快 Overview TCP (Transmission Control Protocol) is the most commonly used protocol on the Internet. The reason for this is because TCP offers error correction. When the TCP protocol is used there is a "guaranteed delivery." This is due largely in part to a method called "flow control." Flow control determines when data needs to be re-sent, and stops the flow of data until previous packets are successfully transferred. This works because if a packet of data is sent, a collision may occur. When this […]
View Details