<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_牛++的博客</title><subtitle type="text">c#.net,aspx,Web,Ajax交流 </subtitle><id>http://feed.cnblogs.com/blog/u/18548/rss</id><updated>2012-02-09T10:23:06Z</updated><author><name>LT</name><uri>http://www.cnblogs.com/niuniu502/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/niuniu502/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/18548/rss"/><entry><id>http://www.cnblogs.com/niuniu502/archive/2012/02/09/2344374.html</id><title type="text">一个好用的C#抓图类</title><summary type="text">The Utilities class. Call Utilities.CaptureWindow(Control.Handle) to capture a specific control: public static class Utilities{ public static Image CaptureScreen() { return CaptureWindow(User32.GetDesktopWindow()); } public static Image CaptureWindow(IntPtr handle) { IntPtr hdcSrc = User...</summary><published>2012-02-09T10:23:00Z</published><updated>2012-02-09T10:23:00Z</updated><author><name>LT</name><uri>http://www.cnblogs.com/niuniu502/</uri></author><link rel="alternate" href="http://www.cnblogs.com/niuniu502/archive/2012/02/09/2344374.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/niuniu502/archive/2012/02/09/2344374.html"/><content type="html">&lt;div&gt;&lt;p&gt;The Utilities class. Call Utilities.CaptureWindow(Control.Handle) to capture a specific control:&lt;/p&gt;  &lt;pre prettyprint"=""&gt;&lt;code&gt;public static class Utilities&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &amp;nbsp; public static Image CaptureScreen()&lt;br /&gt;&amp;nbsp; &amp;nbsp; {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return CaptureWindow(User32.GetDesktopWindow());&lt;br /&gt;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; public static Image CaptureWindow(IntPtr handle)&lt;br /&gt;&amp;nbsp; &amp;nbsp; {&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; IntPtr hdcSrc = User32.GetWindowDC(handle);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; RECT windowRect = new RECT();&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; User32.GetWindowRect(handle, ref windowRect);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int width = windowRect.right - windowRect.left;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int height = windowRect.bottom - windowRect.top;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc);&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap);&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, ApiConstants.SRCCOPY);&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Gdi32.SelectObject(hdcDest, hOld);&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Gdi32.DeleteDC(hdcDest);&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; User32.ReleaseDC(handle, hdcSrc);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Image image = Image.FromHbitmap(hBitmap);&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Gdi32.DeleteObject(hBitmap);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return image;&lt;br /&gt;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;The Gdi32 class:&lt;/p&gt;  &lt;pre prettyprint"=""&gt;&lt;code&gt;public class Gdi32&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &amp;nbsp; [DllImport("gdi32.dll")]&lt;br /&gt;&amp;nbsp; &amp;nbsp; public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjectSource, int nXSrc, int nYSrc, int dwRop);&lt;br /&gt;&amp;nbsp; &amp;nbsp; [DllImport("gdi32.dll")]&lt;br /&gt;&amp;nbsp; &amp;nbsp; public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, int nHeight);&lt;br /&gt;&amp;nbsp; &amp;nbsp; [DllImport("gdi32.dll")]&lt;br /&gt;&amp;nbsp; &amp;nbsp; public static extern IntPtr CreateCompatibleDC(IntPtr hDC);&lt;br /&gt;&amp;nbsp; &amp;nbsp; [DllImport("gdi32.dll")]&lt;br /&gt;&amp;nbsp; &amp;nbsp; public static extern bool DeleteDC(IntPtr hDC);&lt;br /&gt;&amp;nbsp; &amp;nbsp; [DllImport("gdi32.dll")]&lt;br /&gt;&amp;nbsp; &amp;nbsp; public static extern bool DeleteObject(IntPtr hObject);&lt;br /&gt;&amp;nbsp; &amp;nbsp; [DllImport("gdi32.dll")]&lt;br /&gt;&amp;nbsp; &amp;nbsp; public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;The User32 class:&lt;/p&gt;  &lt;pre prettyprint"=""&gt;&lt;code&gt;public static class User32&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &amp;nbsp; [DllImport("user32.dll")]&lt;br /&gt;&amp;nbsp; &amp;nbsp; public static extern IntPtr GetDesktopWindow();&lt;br /&gt;&amp;nbsp; &amp;nbsp; [DllImport("user32.dll")]&lt;br /&gt;&amp;nbsp; &amp;nbsp; public static extern IntPtr GetWindowDC(IntPtr hWnd);&lt;br /&gt;&amp;nbsp; &amp;nbsp; [DllImport("user32.dll")]&lt;br /&gt;&amp;nbsp; &amp;nbsp; public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);&lt;br /&gt;&amp;nbsp; &amp;nbsp; [DllImport("user32.dll")]&lt;br /&gt;&amp;nbsp; &amp;nbsp; public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;The constants used:&lt;/p&gt;  &lt;pre prettyprint"=""&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; public const int SRCCOPY = 13369376;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;The structs used:&lt;/p&gt;  &lt;pre prettyprint"=""&gt;&lt;code&gt;[StructLayout(LayoutKind.Sequential)]&lt;br /&gt;public struct RECT&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &amp;nbsp; public int left;&lt;br /&gt;&amp;nbsp; &amp;nbsp; public int top;&lt;br /&gt;&amp;nbsp; &amp;nbsp; public int right;&lt;br /&gt;&amp;nbsp; &amp;nbsp; public int bottom;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;A friendly Control extension method:&lt;/p&gt;  &lt;pre prettyprint"=""&gt;&lt;code&gt;public static class ControlExtensions&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &amp;nbsp; public static Image DrawToImage(this Control control)&lt;br /&gt;&amp;nbsp; &amp;nbsp; {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return Utilities.CaptureWindow(control.Handle);&lt;br /&gt;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;This is a code snippet from my &lt;a href="http://ccutilities.codeplex.com/" rel="nofollow"&gt;CC.Utilities&lt;/a&gt; project and I specifically wrote it to take screenshots from the WebBrowser control.&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/niuniu502/aggbug/2344374.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/niuniu502/archive/2012/02/09/2344374.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/niuniu502/archive/2012/02/05/2339347.html</id><title type="text">【转】WinSocket编程——原始套接字</title><summary type="text">http://blog.csdn.net/dylgsy/article/details/1957138</summary><published>2012-02-05T14:17:00Z</published><updated>2012-02-05T14:17:00Z</updated><author><name>LT</name><uri>http://www.cnblogs.com/niuniu502/</uri></author><link rel="alternate" href="http://www.cnblogs.com/niuniu502/archive/2012/02/05/2339347.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/niuniu502/archive/2012/02/05/2339347.html"/><content type="html">&lt;a title="http://blog.csdn.net/dylgsy/article/details/1957138" href="http://blog.csdn.net/dylgsy/article/details/1957138"&gt;http://blog.csdn.net/dylgsy/article/details/1957138&lt;/a&gt;&lt;img src="http://www.cnblogs.com/niuniu502/aggbug/2339347.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/niuniu502/archive/2012/02/05/2339347.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/niuniu502/archive/2012/02/05/2339345.html</id><title type="text">【转】SHarpPcap(winpcap基于c#封转的库)网络嗅探程序核心</title><summary type="text">1. 获得网络设备 由于一个系统的网络设备可能不止一个,因而使用了一个列表类来保存所有的设备,这里使用了一个静态方法进行操作 /* Retrieve the device list */ PcapDeviceList devices = SharpPcap.GetAllDevices(); 获取列表后,就能对设备进行操作了,其实设备分为2个子类,一类是NetworkDevice,这个是算是真实的网络设备吧,还有一类是PcapOfflineDevice,这个类是通过读取抓包文件生成的虚拟设备. 如果是NetworkDevice,那么还有些其他的网络信息,如ip地址,子网掩码等. 2....</summary><published>2012-02-05T14:16:00Z</published><updated>2012-02-05T14:16:00Z</updated><author><name>LT</name><uri>http://www.cnblogs.com/niuniu502/</uri></author><link rel="alternate" href="http://www.cnblogs.com/niuniu502/archive/2012/02/05/2339345.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/niuniu502/archive/2012/02/05/2339345.html"/><content type="html">&lt;div&gt;&lt;p&gt;1. 获得网络设备&lt;/p&gt;  &lt;p&gt;由于一个系统的网络设备可能不止一个,因而使用了一个列表类来保存所有的设备,这里使用了一个静态方法进行操作&lt;/p&gt;  &lt;p&gt;/* Retrieve the device list */&lt;/p&gt;  &lt;p&gt;PcapDeviceList devices = SharpPcap.GetAllDevices();&lt;/p&gt;  &lt;p&gt;获取列表后,就能对设备进行操作了,其实设备分为2个子类,一类是NetworkDevice,这个是算是真实的网络设备吧,还有一类是PcapOfflineDevice,这个类是通过读取抓包文件生成的虚拟设备.&lt;/p&gt;  &lt;p&gt;如果是NetworkDevice,那么还有些其他的网络信息,如ip地址,子网掩码等.&lt;/p&gt;  &lt;p&gt;2. 抓包过程&lt;/p&gt;  &lt;p&gt;在选定了一个PcapDevice后,就能使用他的方法进行抓包了.首先要打开设备.&lt;/p&gt;  &lt;p&gt;//Open the device for capturing&lt;/p&gt;  &lt;p&gt;//true -- means promiscuous mode&lt;/p&gt;  &lt;p&gt;//1000 -- means a read wait of 1000ms&lt;/p&gt;  &lt;p&gt;device.PcapOpen(true, 1000);&lt;/p&gt;  &lt;p&gt;方法提供2个参数,第一个为抓包模式,指明是否抓其他Ip地址的包,类似Hub的功能;第二个是指超时时间,毫秒级.&lt;/p&gt;  &lt;p&gt;下面就能正式抓包了,一共提供了3种方法:&lt;/p&gt;  &lt;p&gt;device.PcapStartCapture();&lt;/p&gt;  &lt;p&gt;异步方式,调用之后立即返回,具体抓下来的包,由PcapOnPacketArrival事件处理.需要停止的时候调用device.PcapStopCapture()进行关闭.&lt;/p&gt;  &lt;p&gt;device.PcapCapture(int packetCount);&lt;/p&gt;  &lt;p&gt;半同步方式,调用后,直到抓到packetCount数量的包才返回., 具体抓下来的包,由PcapOnPacketArrival事件处理.&lt;/p&gt;  &lt;p&gt;注意:如果传入SharpPcap.INFINITE将不退出,永远都在接收,且程序就停在这个语句了.&lt;/p&gt;  &lt;p&gt;packet=device.PcapGetNextPacket()&lt;/p&gt;  &lt;p&gt;同步方式,调用后直接等待收到的下一个包,并获得该包.&lt;/p&gt;  &lt;p&gt;注意:如果超时,就可能还没有获得包体就退出该过程.这时packet=null,所以使用该方法每次都要对包进行检测.&lt;/p&gt;  &lt;p&gt;最后一定要记得,关闭设备.&lt;/p&gt;  &lt;p&gt;device.Close();&lt;/p&gt;  &lt;p&gt;3. 包体分析.&lt;/p&gt;  &lt;p&gt;在捕捉到包后,就需要根据实际的包进行转换了. &lt;/p&gt;  &lt;p&gt;if(packet is TCPPacket)&lt;/p&gt;  &lt;p&gt;{&lt;/p&gt;  &lt;p&gt;TCPPacket tcp = (TCPPacket)packet;&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;p&gt;因为这个需要转换的包类型很多,具体都在Tamir.IPLib.Packets里面.按照说明,一直尝试转换是不对的了,需要与过滤机制配合使用,只对自己有用的包分析&lt;/p&gt;  &lt;p&gt;4. 过滤机制&lt;/p&gt;  &lt;p&gt;包过滤是抓包程序的必备机制,要想对某次捕捉进行过滤,就必须在设备打开后,开始抓包前设置设备的过滤参数.&lt;/p&gt;  &lt;p&gt;//tcpdump filter to capture only TCP/IP packets&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;  &lt;p&gt;string filter = "ip and tcp";&lt;/p&gt;  &lt;p&gt;//Associate the filter with this capture&lt;/p&gt;  &lt;p&gt;device.PcapSetFilter( filter );&lt;/p&gt;  &lt;p&gt;注意的是,filter是一个文本,遵循了tcpdump syntax.&lt;/p&gt;  &lt;p&gt;5. 其他&lt;/p&gt;  &lt;p&gt;A. SharpPcap还能保存捕获的包,而且使用起来也很简单.&lt;/p&gt;  &lt;p&gt;保存: 在抓包前设置Dump的文件&lt;/p&gt;  &lt;p&gt;//Open or create a capture output file&lt;/p&gt;  &lt;p&gt;device.PcapDumpOpen( capFile);&lt;/p&gt;  &lt;p&gt;抓到包后,把需要的包保存起来&lt;/p&gt;  &lt;p&gt;//dump the packet to the file&lt;/p&gt;  &lt;p&gt;device.PcapDump( packet );&lt;/p&gt;  &lt;p&gt;使用:把包文件当作一个脱机设备&lt;/p&gt;  &lt;p&gt;//Get an offline file pcap device&lt;/p&gt;  &lt;p&gt;device = SharpPcap.GetPcapOfflineDevice( capFile );&lt;/p&gt;  &lt;p&gt;然后这个设备也可以捕捉包,使用起来和真实的一样(当然,不会有超时了就是)&lt;/p&gt;  &lt;p&gt;B.对设备直接发包&lt;/p&gt;  &lt;p&gt;相对与捕捉包,也可以发送包.提供了2种方法&lt;/p&gt;  &lt;p&gt;//Send the packet out the network device,直接发送包&lt;/p&gt;  &lt;p&gt;device.PcapSendPacket( bytes );&lt;/p&gt;  &lt;p&gt;//使用设备的发送队列&lt;/p&gt;  &lt;p&gt;device.PcapSendQueue(squeue, true );&lt;/p&gt;  &lt;p&gt;两种显然上面的容易,下面的高效&lt;/p&gt;  &lt;p&gt;C.网络流量统计&amp;#8212;没看,我暂时也不想用.&lt;/p&gt;  &lt;p&gt;6.总结&lt;/p&gt;  &lt;p&gt;主要来说PcapDevice类是整个操作的核心,把它用好了就成.&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/niuniu502/aggbug/2339345.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/niuniu502/archive/2012/02/05/2339345.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/niuniu502/archive/2012/02/03/2337493.html</id><title type="text">[心得] socket 多路复用误区</title><summary type="text">最近设计了个UDP服务器，开始只使用一个socket进行收发，结果数据一多，一个socket异步收发（基于IO完成端口）出现N多问题。 所以只能分开两个socket搞了，找了下文章。首先udp和tcp不一样，tcp同一个端口只能一个listen，UDP则可以同时监听（当然只能其中一个获得数据，按规则匹配） 1、UDP多路复用的是按最小规范集转发数据的。例如A bing any ， b bing 127.0.01，这时如果收到一个地址为127.0.0.1的包，那么b的绑定记录显然更详细，B得到了数据，A收不到。如果非127.0.01的本机地址按AB的绑定分析后则是a获得数据。 2、如果A\B都绑</summary><published>2012-02-03T10:52:00Z</published><updated>2012-02-03T10:52:00Z</updated><author><name>LT</name><uri>http://www.cnblogs.com/niuniu502/</uri></author><link rel="alternate" href="http://www.cnblogs.com/niuniu502/archive/2012/02/03/2337493.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/niuniu502/archive/2012/02/03/2337493.html"/><content type="html">&lt;p&gt;最近设计了个UDP服务器，开始只使用一个socket进行收发，结果数据一多，一个socket异步收发（基于IO完成端口）出现N多问题。 &lt;br /&gt;&lt;/p&gt;&lt;p&gt;所以只能分开两个socket搞了，找了下文章。&lt;/p&gt;&lt;p&gt;首先udp和tcp不一样，tcp同一个端口只能一个listen，UDP则可以同时监听（当然只能其中一个获得数据，按规则匹配） &lt;br /&gt;&lt;/p&gt;&lt;p&gt;1、UDP多路复用的是按最小规范集转发数据的。&lt;/p&gt;&lt;p&gt;例如A bing any ， b bing 127.0.01，这时如果收到一个地址为127.0.0.1的包，那么b的绑定记录显然更详细，B得到了数据，A收不到。&lt;/p&gt;&lt;p&gt;如果非127.0.01的本机地址按AB的绑定分析后则是a获得数据。 &lt;br /&gt;&lt;/p&gt;&lt;p&gt;2、如果A\B都绑定any（规则一样） 则是最后绑定的收到数据，条件相同就后入先得。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;我一开始的时候也是犯2了，a用来监听，死活听不到，后来把A放到b后bind 就没事了。。。。囧。&lt;/p&gt;&lt;p&gt;这文章是给初涉socket提个醒了。 &lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/niuniu502/aggbug/2337493.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/niuniu502/archive/2012/02/03/2337493.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/niuniu502/archive/2012/02/02/2335240.html</id><title type="text">UDP 异步 收发 服务端例子 【转载】</title><summary type="text">采用异步模式设计的UDP服务器，源码如下： 1 using System; 2 using System.Net; 3 using System.Net.Sockets; 4 using System.ServiceProcess; 5 using System.Threading; 6 7 namespace TestUdpServer 8 { 9 // this class encapsulates a single packet that 10 // is either sent or received by a UDP socket 11 public ...</summary><published>2012-02-01T16:14:00Z</published><updated>2012-02-01T16:14:00Z</updated><author><name>LT</name><uri>http://www.cnblogs.com/niuniu502/</uri></author><link rel="alternate" href="http://www.cnblogs.com/niuniu502/archive/2012/02/02/2335240.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/niuniu502/archive/2012/02/02/2335240.html"/><content type="html">&lt;div&gt;&lt;p&gt;采用异步模式设计的UDP服务器，源码如下：&lt;/p&gt; &lt;p&gt;&lt;/p&gt;&lt;div&gt; &lt;pre&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;  1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  2&lt;/span&gt; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Net;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  3&lt;/span&gt; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Net.Sockets;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.ServiceProcess;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Threading;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  6&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt; TestUdpServer&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  8&lt;/span&gt; &lt;span style="color: #000000;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  9&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; this class encapsulates a single packet that&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 10&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; is either sent or received by a UDP socket&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 11&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; UDPPacketBuffer&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 12&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 13&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; size of the buffer&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 14&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; BUFFER_SIZE &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt; &lt;span style="color: #800080;"&gt;4096&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 15&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 16&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; the buffer itself&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 17&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] Data;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 18&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 19&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; length of data to transmit&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 20&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; DataLength;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 21&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 22&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; the (IP)Endpoint of the remote host&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 23&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; EndPoint RemoteEndPoint;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 24&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 25&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; UDPPacketBuffer()&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 26&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 27&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Data &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;&lt;span style="color: #000000;"&gt;[BUFFER_SIZE];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 28&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 29&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; this will be filled in by the call to udpSocket.BeginReceiveFrom&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 30&lt;/span&gt; &lt;span style="color: #000000;"&gt;            RemoteEndPoint &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; (EndPoint)&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; IPEndPoint(IPAddress.Any, &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 31&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 32&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 33&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; UDPPacketBuffer(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] data, EndPoint remoteEndPoint)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 34&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 35&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Data &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; data;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 36&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.DataLength &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; data.Length;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 37&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.RemoteEndPoint &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; remoteEndPoint;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 38&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 39&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 40&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 41&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;abstract&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; UDPServer&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 42&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 43&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; the port to listen on&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 44&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; udpPort;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 45&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 46&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; the UDP socket&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 47&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; Socket udpSocket;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 48&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 49&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; the ReaderWriterLock is used solely for the purposes of shutdown (Stop()).&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 50&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; since there are potentially many "reader" threads in the internal .NET IOCP&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 51&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; thread pool, this is a cheaper synchronization primitive than using&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 52&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; a Mutex object.  This allows many UDP socket "reads" concurrently - when&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 53&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Stop() is called, it attempts to obtain a writer lock which will then&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 54&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; wait until all outstanding operations are completed before shutting down.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 55&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; this avoids the problem of closing the socket with outstanding operations&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 56&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; and trying to catch the inevitable ObjectDisposedException.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 57&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; ReaderWriterLock rwLock &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ReaderWriterLock();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 58&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 59&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; number of outstanding operations.  This is a reference count&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 60&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; which we use to ensure that the threads exit cleanly. Note that&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 61&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; we need this because the threads will potentially still need to process&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 62&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; data even after the socket is closed.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 63&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; rwOperationCount &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt; &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 64&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 65&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; the all important shutdownFlag.  This is synchronized through the ReaderWriterLock.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 66&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&lt;span style="color: #000000;"&gt; shutdownFlag &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 67&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 68&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; these abstract methods must be implemented in a derived class to actually do&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 69&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; something with the packets that are sent and received.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 70&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;abstract&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; PacketReceived(UDPPacketBuffer buffer);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 71&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;abstract&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; PacketSent(UDPPacketBuffer buffer, &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; bytesSent);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 72&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 73&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; ServiceName&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 74&lt;/span&gt; &lt;span style="color: #000000;"&gt;        String ServiceName &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 75&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 76&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; UDPServer(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; port)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 77&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 78&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.udpPort &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; port;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 79&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 80&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 81&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Start()&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 82&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 83&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (shutdownFlag)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 84&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 85&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; create and bind the socket&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 86&lt;/span&gt; &lt;span style="color: #000000;"&gt;                IPEndPoint ipep &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; IPEndPoint(IPAddress.Any, udpPort);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 87&lt;/span&gt; &lt;span style="color: #000000;"&gt;                udpSocket &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Socket(&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 88&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    AddressFamily.InterNetwork,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 89&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    SocketType.Dgram,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 90&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    ProtocolType.Udp);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 91&lt;/span&gt; &lt;span style="color: #000000;"&gt;                udpSocket.Bind(ipep);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 92&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; we're not shutting down, we're starting up&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 93&lt;/span&gt; &lt;span style="color: #000000;"&gt;                shutdownFlag &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 94&lt;/span&gt; &lt;span style="color: #000000;"&gt;                &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 95&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; kick off an async receive.  The Start() method will return, the&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 96&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; actual receives will occur asynchronously and will be caught in&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 97&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; AsyncEndRecieve().&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 98&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; I experimented with posting multiple AsyncBeginReceives() here in an attempt&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 99&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; to "queue up" reads, however I found that it negatively impacted performance.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;100&lt;/span&gt; &lt;span style="color: #000000;"&gt;                AsyncBeginReceive();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;101&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;102&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;103&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;104&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Stop()&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;105&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;106&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;shutdownFlag)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;107&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;108&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; wait indefinitely for a writer lock.  Once this is called, the .NET runtime&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;109&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; will deny any more reader locks, in effect blocking all other send/receive&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;110&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; threads.  Once we have the lock, we set shutdownFlag to inform the other&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;111&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; threads that the socket is closed.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;112&lt;/span&gt; &lt;span style="color: #000000;"&gt;                rwLock.AcquireWriterLock(&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;113&lt;/span&gt; &lt;span style="color: #000000;"&gt;                shutdownFlag &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;114&lt;/span&gt; &lt;span style="color: #000000;"&gt;                udpSocket.Close();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;115&lt;/span&gt; &lt;span style="color: #000000;"&gt;                rwLock.ReleaseWriterLock();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;116&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;117&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; wait for any pending operations to complete on other&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;118&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; threads before exiting.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;119&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; (rwOperationCount &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;120&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    Thread.Sleep(&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;121&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;122&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;123&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;124&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&lt;span style="color: #000000;"&gt; IsRunning&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;125&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;126&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; self-explanitory&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;127&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt; { &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;shutdownFlag; }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;128&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;129&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;130&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; AsyncBeginReceive()&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;131&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;132&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; this method actually kicks off the async read on the socket.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;133&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; we aquire a reader lock here to ensure that no other thread&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;134&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; is trying to set shutdownFlag and close the socket.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;135&lt;/span&gt; &lt;span style="color: #000000;"&gt;            rwLock.AcquireReaderLock(&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;136&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;137&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;shutdownFlag)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;138&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;139&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; increment the count of pending operations&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;140&lt;/span&gt; &lt;span style="color: #000000;"&gt;                Interlocked.Increment(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt;&lt;span style="color: #000000;"&gt; rwOperationCount);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;141&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;142&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; allocate a packet buffer&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;143&lt;/span&gt; &lt;span style="color: #000000;"&gt;                UDPPacketBuffer buf &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; UDPPacketBuffer();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;144&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;145&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;146&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;147&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; kick off an async read&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;148&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    udpSocket.BeginReceiveFrom(&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;149&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        buf.Data,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;150&lt;/span&gt;  &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;151&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        UDPPacketBuffer.BUFFER_SIZE,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;152&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        SocketFlags.None,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;153&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt;&lt;span style="color: #000000;"&gt; buf.RemoteEndPoint,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;154&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; AsyncCallback(AsyncEndReceive),&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;155&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        buf);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;156&lt;/span&gt; &lt;span style="color: #000000;"&gt;                }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;157&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt;&lt;span style="color: #000000;"&gt; (SocketException se)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;158&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;159&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; something bad happened&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;160&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    System.Diagnostics.EventLog.WriteEntry(ServiceName,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;161&lt;/span&gt;  &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;A SocketException occurred in UDPServer.AsyncBeginReceive():\n\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; &lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; se.Message,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;162&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        System.Diagnostics.EventLogEntryType.Error);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;163&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;164&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; an error occurred, therefore the operation is void.  Decrement the reference count.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;165&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    Interlocked.Decrement(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt;&lt;span style="color: #000000;"&gt; rwOperationCount);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;166&lt;/span&gt; &lt;span style="color: #000000;"&gt;                }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;167&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;168&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;169&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; we're done with the socket for now, release the reader lock.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;170&lt;/span&gt; &lt;span style="color: #000000;"&gt;            rwLock.ReleaseReaderLock();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;171&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;172&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;173&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; AsyncEndReceive(IAsyncResult iar)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;174&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;175&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Asynchronous receive operations will complete here through the call&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;176&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; to AsyncBeginReceive&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;177&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;178&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; aquire a reader lock&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;179&lt;/span&gt; &lt;span style="color: #000000;"&gt;            rwLock.AcquireReaderLock(&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;180&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;181&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;shutdownFlag)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;182&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;183&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; start another receive - this keeps the server going!&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;184&lt;/span&gt; &lt;span style="color: #000000;"&gt;                AsyncBeginReceive();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;185&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;186&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; get the buffer that was created in AsyncBeginReceive&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;187&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; this is the received data&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;188&lt;/span&gt; &lt;span style="color: #000000;"&gt;                UDPPacketBuffer buffer &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; (UDPPacketBuffer)iar.AsyncState;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;189&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;190&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;191&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;192&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; get the length of data actually read from the socket, store it with the&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;193&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; buffer&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;194&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    buffer.DataLength &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; udpSocket.EndReceiveFrom(iar, &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt;&lt;span style="color: #000000;"&gt; buffer.RemoteEndPoint);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;195&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;196&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; this operation is now complete, decrement the reference count&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;197&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    Interlocked.Decrement(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt;&lt;span style="color: #000000;"&gt; rwOperationCount);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;198&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;199&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; we're done with the socket, release the reader lock&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;200&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    rwLock.ReleaseReaderLock();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;201&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;202&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; call the abstract method PacketReceived(), passing the buffer that&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;203&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; has just been filled from the socket read.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;204&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    PacketReceived(buffer);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;205&lt;/span&gt; &lt;span style="color: #000000;"&gt;                }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;206&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt;&lt;span style="color: #000000;"&gt; (SocketException se)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;207&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;208&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; something bad happened&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;209&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    System.Diagnostics.EventLog.WriteEntry(ServiceName,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;210&lt;/span&gt;  &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;A SocketException occurred in UDPServer.AsyncEndReceive():\n\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; &lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; se.Message,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;211&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        System.Diagnostics.EventLogEntryType.Error);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;212&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;213&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; an error occurred, therefore the operation is void.  Decrement the reference count.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;214&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    Interlocked.Decrement(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt;&lt;span style="color: #000000;"&gt; rwOperationCount);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;215&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;216&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; we're done with the socket for now, release the reader lock.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;217&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    rwLock.ReleaseReaderLock();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;218&lt;/span&gt; &lt;span style="color: #000000;"&gt;                }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;219&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;220&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;221&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;222&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; nothing bad happened, but we are done with the operation&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;223&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; decrement the reference count and release the reader lock&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;224&lt;/span&gt; &lt;span style="color: #000000;"&gt;                Interlocked.Decrement(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt;&lt;span style="color: #000000;"&gt; rwOperationCount);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;225&lt;/span&gt; &lt;span style="color: #000000;"&gt;                rwLock.ReleaseReaderLock();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;226&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;227&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;228&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;229&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; AsyncBeginSend(UDPPacketBuffer buf)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;230&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;231&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; by now you should you get the idea - no further explanation necessary&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;232&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;233&lt;/span&gt; &lt;span style="color: #000000;"&gt;            rwLock.AcquireReaderLock(&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;234&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;235&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;shutdownFlag)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;236&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;237&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;238&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;239&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    Interlocked.Increment(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt;&lt;span style="color: #000000;"&gt; rwOperationCount);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;240&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    udpSocket.BeginSendTo(&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;241&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        buf.Data,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;242&lt;/span&gt;  &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;243&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        buf.DataLength,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;244&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        SocketFlags.None,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;245&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        buf.RemoteEndPoint,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;246&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; AsyncCallback(AsyncEndSend),&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;247&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        buf);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;248&lt;/span&gt; &lt;span style="color: #000000;"&gt;                }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;249&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt;&lt;span style="color: #000000;"&gt; (SocketException se)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;250&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;251&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    System.Diagnostics.EventLog.WriteEntry(ServiceName,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;252&lt;/span&gt;  &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;A SocketException occurred in UDPServer.AsyncBeginSend():\n\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; &lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; se.Message,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;253&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        System.Diagnostics.EventLogEntryType.Error);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;254&lt;/span&gt; &lt;span style="color: #000000;"&gt;                }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;255&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;256&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;257&lt;/span&gt; &lt;span style="color: #000000;"&gt;            rwLock.ReleaseReaderLock();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;258&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;259&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;260&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; AsyncEndSend(IAsyncResult iar)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;261&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;262&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; by now you should you get the idea - no further explanation necessary&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;263&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;264&lt;/span&gt; &lt;span style="color: #000000;"&gt;            rwLock.AcquireReaderLock(&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;265&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;266&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;shutdownFlag)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;267&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;268&lt;/span&gt; &lt;span style="color: #000000;"&gt;                UDPPacketBuffer buffer &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; (UDPPacketBuffer)iar.AsyncState;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;269&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;270&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;271&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;272&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; bytesSent &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; udpSocket.EndSendTo(iar);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;273&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;274&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; note that call to the abstract PacketSent() method - we are passing the number&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;275&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; of bytes sent in a separate parameter, since we can't use buffer.DataLength which&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;276&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; is the number of bytes to send (or bytes received depending upon whether this&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;277&lt;/span&gt;  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; buffer was part of a send or a receive).&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;278&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    PacketSent(buffer, bytesSent);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;279&lt;/span&gt; &lt;span style="color: #000000;"&gt;                }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;280&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt;&lt;span style="color: #000000;"&gt; (SocketException se)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;281&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;282&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    System.Diagnostics.EventLog.WriteEntry(ServiceName,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;283&lt;/span&gt;  &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;A SocketException occurred in UDPServer.AsyncEndSend():\n\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; &lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; se.Message,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;284&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        System.Diagnostics.EventLogEntryType.Error);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;285&lt;/span&gt; &lt;span style="color: #000000;"&gt;                }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;286&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;287&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;288&lt;/span&gt; &lt;span style="color: #000000;"&gt;            Interlocked.Decrement(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt;&lt;span style="color: #000000;"&gt; rwOperationCount);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;289&lt;/span&gt; &lt;span style="color: #000000;"&gt;            rwLock.ReleaseReaderLock();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;290&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;291&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;292&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;293&lt;/span&gt; &lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt; &lt;div&gt;&lt;a&gt;复制代码&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;实际使用时需继承抽象类UDPServer，并实现异步处理数据的相关方案，示例如下：&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt;&lt;div&gt; &lt;pre&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Collections.Generic;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Text;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Runtime.InteropServices;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt; TestUdpServer&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; TUdpServer : UDPServer&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; TUdpServer(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; port)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;            : &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;(port)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;            Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Server Start...@&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; &lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; port.ToString());&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; PacketReceived(UDPPacketBuffer buffer)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;span style="color: #000000;"&gt;            AsyncBeginSend(buffer);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; PacketSent(UDPPacketBuffer buffer, &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; bytesSent)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; &lt;span style="color: #000000;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; &lt;/div&gt;&lt;/pre&gt; &lt;div&gt;&lt;a&gt;复制代码&lt;/a&gt;&lt;/div&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/niuniu502/aggbug/2335240.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/niuniu502/archive/2012/02/02/2335240.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/niuniu502/archive/2012/02/01/2335079.html</id><title type="text">UDPClient 的奇特现象，实在搞不懂</title><summary type="text">我有个项目，设计了一个UDP服务端。是通过UDPCLIENT 的一个实例（同一端口）提供收发服务。当项目上线测试后，奇怪的现象发生。如果重启过服务器的话，服务器可以运行一段较长时间无异常。但一段时间之后，奇怪的事情来了。1、例如之前有A\B\C等N个客户端已经连接到服务端，服务端一直持续为它们 提供服务，然后在正常运行一段时间后，ABC的数据都会变得不正常，服务端无法再正常解析数据提供服务了。客户数据是可以接收到，但已经不正确了。2、然后更搞笑的是，如果有新入的连接（不同的IP），服务端却又能正常提供为该客户服务，但服务一段时间后，就会表现和ABC一样。然后重复上面的两个问题 ，不断累积，反.</summary><published>2012-02-01T12:33:00Z</published><updated>2012-02-01T12:33:00Z</updated><author><name>LT</name><uri>http://www.cnblogs.com/niuniu502/</uri></author><link rel="alternate" href="http://www.cnblogs.com/niuniu502/archive/2012/02/01/2335079.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/niuniu502/archive/2012/02/01/2335079.html"/><content type="html">&lt;p&gt;我有个项目，设计了一个UDP服务端。&lt;/p&gt;&lt;p&gt;是通过UDPCLIENT 的一个实例（同一端口）提供收发服务。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;当项目上线测试后，奇怪的现象发生。&lt;/p&gt;&lt;p&gt;如果重启过服务器的话，服务器可以运行一段较长时间无异常。&lt;/p&gt;&lt;p&gt;但一段时间之后，奇怪的事情来了。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;1、例如之前有A\B\C等N个客户端已经连接到服务端，服务端一直持续为它们 提供服务，然后在正常运行一段时间后，ABC的数据都会变得不正常，服务端无法再正常解析数据提供服务了。客户数据是可以接收到，但已经不正确了。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;2、然后更搞笑的是，如果有新入的连接（不同的IP），服务端却又能正常提供为该客户服务，但服务一段时间后，就会表现和ABC一样。&lt;/p&gt;&lt;p&gt;然后重复上面的两个问题 ，不断累积，反正有新客户（不同的IP）就正常服务，但不定什么时候就不正常了。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;我的接收是通过异步BeginReceive投递的，而发送则是以阻塞方式Send &lt;br /&gt;&lt;/p&gt;&lt;p&gt;其中EndReceive也进行了线程同步， UDP的接收缓冲区我也设置得足够大了，TCP连接限制和端口可用数我也修改过，但问题依然无法解决。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;让这个问题搞了几天了，希望大家能提供些思路和解决办法 ，真的古怪&lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/niuniu502/aggbug/2335079.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/niuniu502/archive/2012/02/01/2335079.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/niuniu502/archive/2012/01/27/2330141.html</id><title type="text">[转载]TCP打开端口数和打开连接数限制系列文章</title><summary type="text">[转载]TCP打开端口数和打开连接数限制系列文章</summary><published>2012-01-27T09:22:00Z</published><updated>2012-01-27T09:22:00Z</updated><author><name>LT</name><uri>http://www.cnblogs.com/niuniu502/</uri></author><link rel="alternate" href="http://www.cnblogs.com/niuniu502/archive/2012/01/27/2330141.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/niuniu502/archive/2012/01/27/2330141.html"/><content type="html">&lt;a title="[转载]TCP打开端口数和打开连接数限制系列文章" href="http://blog.csdn.net/raphaelliu/article/details/6177900"&gt;[转载]TCP打开端口数和打开连接数限制系列文章&lt;/a&gt;&lt;img src="http://www.cnblogs.com/niuniu502/aggbug/2330141.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/niuniu502/archive/2012/01/27/2330141.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/niuniu502/archive/2012/01/16/2324192.html</id><title type="text">UDP错误10054:远程主机强迫关闭的解决方法---转载</title><summary type="text">UDP错误10054:远程主机强迫关闭了一个现有的连接 原文地址:http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic1887.aspx 在 公司一项目的UDP消息服务开发中时不时的会遇到这样一个问题：在UDP通信过程中，如果客户端中途断开，服务器会收到一个 SocketException，错误ID为10054，描述是“远程主机强迫关闭了一个现有的连接”，紧接着的事就可怕了，UDP服务终止监听，所有客 户端都受到了影响。也就是说一个客户端引起的异常导致了整个系统的崩溃。这个问题可...</summary><published>2012-01-16T15:26:00Z</published><updated>2012-01-16T15:26:00Z</updated><author><name>LT</name><uri>http://www.cnblogs.com/niuniu502/</uri></author><link rel="alternate" href="http://www.cnblogs.com/niuniu502/archive/2012/01/16/2324192.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/niuniu502/archive/2012/01/16/2324192.html"/><content type="html">&lt;div&gt;&lt;p&gt;&lt;strong&gt; 			&lt;a id="ctl02_TitleUrl" href="http://www.cnblogs.com/Lotrix/archive/2011/05/06/2038666.html"&gt;UDP错误10054:远程主机强迫关闭了一个现有的连接&lt;/a&gt; 		&lt;/strong&gt;&lt;/p&gt; 		&lt;div id="cnblogs_post_body"&gt;&lt;p&gt;原文地址:&lt;a title="http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic1887.aspx" href="http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic1887.aspx"&gt;http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic1887.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;在 公司一项目的UDP消息服务开发中时不时的会遇到这样一个问题：在UDP通信过程中，如果客户端中途断开，服务器会收到一个 SocketException，错误ID为10054，描述是&amp;#8220;远程主机强迫关闭了一个现有的连接&amp;#8221;，紧接着的事就可怕了，UDP服务终止监听，所有客 户端都受到了影响。也就是说一个客户端引起的异常导致了整个系统的崩溃。这个问题可是太严重了。&lt;/p&gt;  &lt;p&gt;地球人都知道，UDP是无连接的，怎么会出现这个异常呢？百度了一圈，发现有这个问题的现象还不少，可就是没有一个有效的回复。再GOOGLE一圈，有点眉目了。找到了一个微软的解释和一个DOTNET的解决方法：&lt;/p&gt;  &lt;p&gt;微软的解释：&lt;a href="http://support.microsoft.com/kb/263823"&gt;http://support.microsoft.com/kb/263823&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;DOTNET的处理方法：&lt;a href="http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic1887.aspx"&gt;http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic1887.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;不过处理方法似乎对参数的设置不太正确：    &lt;br /&gt;byte[] optionInValue = { Convert.ToByte(true) };     &lt;br /&gt;byte[] optionOutValue;&lt;/p&gt;  &lt;p&gt;按照这样设置还是会抛出该异常。    &lt;br /&gt;首先，根据微软的解释，optionInValue 传入的应该是false，而不是true；     &lt;br /&gt;其次，根据微软的解释，optionOutValue应该是一个DWORD值，不应不赋值，或设为null。&lt;/p&gt;  &lt;p&gt;根据以上两点，将以上两句改为：    &lt;br /&gt;byte[] optionInValue = { Convert.ToByte(false) };     &lt;br /&gt;byte[] optionOutValue = new byte[4];&lt;/p&gt;  &lt;p&gt;经过测试，模拟500个用户进行登录、收发消息、注销、异常退出、再连接，均没有再抛出该异常。服务表现稳定。&lt;/p&gt;  &lt;p&gt;在 UDP通信过程中，如果客户端中途断开，服务器会收到一个SocketException，错误ID为10054，描述是&amp;#8220;远程主机强迫关闭了一个现有的 连接&amp;#8221;，紧接着的事就可怕了，UDP服务终止监听，所有客户端都受到了影响。也就是说一个客户端引起的异常导致了整个系统的崩溃。&lt;/p&gt;  &lt;p&gt;找了好几天了。终于找到了解决办法。&lt;/p&gt;  &lt;p&gt;在初始化对象后设置属性如下：&lt;/p&gt;  &lt;p&gt;uint IOC_IN = 0x80000000;    &lt;br /&gt;uint IOC_VENDOR = 0x18000000;     &lt;br /&gt;uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;     &lt;br /&gt;ClientSocket.IOControl((int)SIO_UDP_CONNRESET, new byte[] {Convert.ToByte(false)}, null);&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Socket.IOControl 方法 (IOControlCode, Byte[], Byte[])&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;使用 &lt;strong&gt;IOControlCode&lt;/strong&gt; 枚举指定控制代码，为 &lt;a href="http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket%28VS.80%29.aspx" name="ctl00_rs1_mainContentContainer_ctl01"&gt;Socket&lt;/a&gt; 设置低级操作模式。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/p&gt; &lt;dl&gt;&lt;dt&gt;&lt;em&gt;ioControlCode&lt;/em&gt;&lt;/dt&gt;&lt;dd&gt;     &lt;p&gt;一个 &lt;a href="http://msdn.microsoft.com/zh-cn/library/system.net.sockets.iocontrolcode%28VS.80%29.aspx" name="ctl00_rs1_mainContentContainer_ctl18"&gt;IOControlCode&lt;/a&gt; 值，它指定要执行的操作的控制代码。&lt;/p&gt;   &lt;/dd&gt;&lt;/dl&gt;&lt;dl&gt;&lt;dt&gt;&lt;em&gt;optionInValue&lt;/em&gt;&lt;/dt&gt;&lt;dd&gt;     &lt;p&gt;&lt;a href="http://msdn.microsoft.com/zh-cn/library/system.byte%28VS.80%29.aspx" name="ctl00_rs1_mainContentContainer_ctl19"&gt;Byte&lt;/a&gt; 类型的数组，包含操作要求的输入数据。&lt;/p&gt;   &lt;/dd&gt;&lt;/dl&gt;&lt;dl&gt;&lt;dt&gt;&lt;em&gt;optionOutValue&lt;/em&gt;&lt;/dt&gt;&lt;dd&gt;     &lt;p&gt;&lt;strong&gt;Byte&lt;/strong&gt; 类型的数组，包含由操作返回的输出数据。&lt;/p&gt;   &lt;/dd&gt;&lt;/dl&gt;  &lt;p&gt;&lt;strong&gt;返回值&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;optionOutValue&lt;/em&gt; 参数中的字节数。&lt;/p&gt;  &lt;p&gt;&lt;img alt="" src="http://i.msdn.microsoft.com/Global/Images/clear.gif" /&gt; 异常&lt;/p&gt;  &lt;p&gt;&lt;a name="exceptionsToggle"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;异常类型    &lt;br /&gt;条件&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socketexception%28VS.80%29.aspx" name="ctl00_rs1_mainContentContainer_ctl26"&gt;SocketException&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;试图访问套接字时发生错误。有关更多信息，请参见备注部分。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/zh-cn/library/system.objectdisposedexception%28VS.80%29.aspx" name="ctl00_rs1_mainContentContainer_ctl27"&gt;ObjectDisposedException&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Socket&lt;/strong&gt; 已关闭。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/zh-cn/library/system.invalidoperationexception%28VS.80%29.aspx" name="ctl00_rs1_mainContentContainer_ctl28"&gt;InvalidOperationException&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;试图不使用 &lt;a href="http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.blocking%28VS.80%29.aspx" name="ctl00_rs1_mainContentContainer_ctl29"&gt;Blocking&lt;/a&gt; 属性更改阻止模式。&lt;/p&gt;  &lt;p&gt;&lt;img alt="" src="http://i.msdn.microsoft.com/Global/Images/clear.gif" /&gt; 备注&lt;/p&gt;  &lt;p&gt;&lt;a name="remarksToggle"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;此方法提供对 &lt;strong&gt;Socket&lt;/strong&gt; 类的当前实例所基于的操作系统 &lt;strong&gt;Socket&lt;/strong&gt; 的低级访问。有关更多信息，请参见 MSDN Library 中的 WSAIoctl 文档。&lt;/p&gt;  &lt;p&gt;本人体会：&lt;/p&gt;  &lt;p&gt;这个问题的是害死不少人&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/niuniu502/aggbug/2324192.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/niuniu502/archive/2012/01/16/2324192.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/niuniu502/archive/2011/11/06/2238246.html</id><title type="text">应用程式上屏蔽flash控件的右键菜单并获得左键消息_c#</title><summary type="text">使用FLASH做界面美化是一种较为常见的方式，FLASH动画制做简单，美观大方，而且将FLASH嵌入到应用程式界面上也是很容易的，只要放置 一个Shockwave Flash控件即可。但这样做出来的界面有两个问题，一是在FLASH上点击右键会有FLASH的菜单，二是在FLASH上点击的鼠标消息从应用程式里是 获取不到的，FLASH控件并不会向用应程式发送WM_LBUTTONDOWN等鼠标消息。解决的办法应该有很多，我使用了自定义窗口过程的方法，经过试验效果不错。以下都基于Visual C 6.0和MFC环境：首先需要为Flash控件生成变量，这一步借助ClassWizard能够轻松完成，...</summary><published>2011-11-06T09:40:00Z</published><updated>2011-11-06T09:40:00Z</updated><author><name>LT</name><uri>http://www.cnblogs.com/niuniu502/</uri></author><link rel="alternate" href="http://www.cnblogs.com/niuniu502/archive/2011/11/06/2238246.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/niuniu502/archive/2011/11/06/2238246.html"/><content type="html">&lt;div&gt;&lt;p&gt;使用FLASH做界面美化是一种较为常见的方式，FLASH动画制做简单，美观大方，而且将FLASH嵌入到应用程式界面上也是很容易的，只要放置 一个Shockwave  Flash控件即可。但这样做出来的界面有两个问题，一是在FLASH上点击右键会有FLASH的菜单，二是在FLASH上点击的鼠标消息从应用程式里是 获取不到的，FLASH控件并不会向用应程式发送WM_LBUTTONDOWN等鼠标消息。&lt;br /&gt;解决的办法应该有很多，我使用了自定义窗口过程的方法，经过试验效果不错。以下都基于Visual C   6.0和MFC环境：&lt;br /&gt;首先需要为Flash控件生成变量，这一步借助ClassWizard能够轻松完成，略过。假如我们生成的Flash对象名为m_Flash1。下面就通过SetWindowLong函数为Flash控件自定义一个窗口过程：&lt;br /&gt;LONG oldWndProc = NULL;&lt;br /&gt;oldWndProc = ::SetWindowLong(m_Flash1.m_hWnd, GWL_WNDPROC, (LONG)MyProc);&lt;br /&gt;其中m_Flash1.m_hWnd用来取得FLASH控件的窗口句柄，常数GWL_WNDPROC表示我们要修改的是窗口过程，MyProc是个自定义的窗口过程，函数返回旧的窗口过程的地址。下面就是这个自定义的窗口过程：&lt;br /&gt;LONG MyProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)&lt;br /&gt;...{&lt;br /&gt;       if(msg == WM_RBUTTONDOWN)     // 屏蔽右键&lt;br /&gt;              return 0;&lt;br /&gt;       return CallWindowProc((WNDPROC)oldWndProc, hwnd, msg, wParam, lParam); //调用原来的窗口过程&lt;br /&gt;}&lt;br /&gt;这 里通过判断消息的类型是不是右键按下来屏蔽右键菜单，假如右键被按下，那么函数就直接返回，不去调用原来的窗口过程，因此右键菜单就不会出现了。假如要捕 获鼠标左键消息，也能够在这里来处理，例如，下面的代码插在return语句之前则能够实现鼠标左键在FLASH上拖动时窗口能够随之拖动的效果：&lt;br /&gt;if(msg == WM_LBUTTONDOWN)     &lt;br /&gt;        PostMessage(AfxGetApp()-&amp;gt;m_pMainWnd-&amp;gt;m_hWnd,  WM_NCLBUTTONDOWN, HTCAPTION,  0);值得注意的是，这里我只是向消息队列里又发送了一个WM_NCLBUTTONDOWN消息，而并没有让函数返回，因此后面的 CallWindowProc仍然会被调用，因此并不会影响到FLASH本身对鼠标左键的处理，使用起来效果很好，几乎看不出来这里是用FLASH制做的 了。&lt;/p&gt;  &lt;p&gt;http://blog.csdn.net/songthin/archive/2007/02/14/1510210.aspx&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/niuniu502/aggbug/2238246.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/niuniu502/archive/2011/11/06/2238246.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/niuniu502/archive/2011/09/21/2184434.html</id><title type="text">AJAX分段下载/读取HTML内容（有效节省带宽加快运行速度）</title><summary type="text">AJAX分段下载/读取HTML内容（有效节省带宽加快运行速度） 本来以为自己已经算是对AJAX技术了如指掌了，因为从3年前就一直用XMLHttpRequest对象做一些无刷新页面的处理工作，但是，直道今天在工作中遇到了一个分段读取内容的问题，我才了解到，自己原来还需要补充。 基本的问题是这样的： 我需要设计一个框架，需要承载500万以上用户访问（公司毕竟是中国用户最多的互联网企业）。我们用了大量的静态化技术，为了应对可能出现的高负载，我们 还是用了一些公司内自主研发的高性能静态WEB服务器。由于页面是静态生成的，我们遇到一个问题，就是如何在某一时刻更新了某个静态文件后，在前台进行 AJA...</summary><published>2011-09-21T12:45:00Z</published><updated>2011-09-21T12:45:00Z</updated><author><name>LT</name><uri>http://www.cnblogs.com/niuniu502/</uri></author><link rel="alternate" href="http://www.cnblogs.com/niuniu502/archive/2011/09/21/2184434.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/niuniu502/archive/2011/09/21/2184434.html"/><content type="html">&lt;div&gt;&lt;div&gt;&lt;strong&gt;AJAX分段下载/读取HTML内容（有效节省带宽加快运行速度）&lt;/strong&gt;&lt;/div&gt; &lt;p&gt;本来以为自己已经算是对AJAX技术了如指掌了，因为从3年前就一直用XMLHttpRequest对象做一些无刷新页面的处理工作，但是，直道今天在工作中遇到了一个分段读取内容的问题，我才了解到，自己原来还需要补充。&lt;/p&gt; &lt;p&gt;基本的问题是这样的：&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  我需要设计一个框架，需要承载500万以上用户访问（公司毕竟是中国用户最多的互联网企业）。我们用了大量的静态化技术，为了应对可能出现的高负载，我们 还是用了一些公司内自主研发的高性能静态WEB服务器。由于页面是静态生成的，我们遇到一个问题，就是如何在某一时刻更新了某个静态文件后，在前台进行 AJAX的加载。起初对这个问题想得比较简单，认为只要加载然后赋值并显示即可，但是在以前血的教训下（当加载的内容非常大，IE浏览器渲染显示的时候会 非常慢，给用户明显的跳动刷新的感觉。），我们决定对于文件进行分段加载，这样做不但解决了一次加载过大文件的问题，同时也为服务器省下了一些处理时间和 资源，尽可能快地结束HTTP请求。&lt;/p&gt; &lt;p&gt;解决方案：&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  我拿到这个问题，在设计的过程中首先考虑的是，分段请求应该就是类似于FlashGet之流，进行分段请求而已，只需要构造自己的HTTPRequest 请求的Headers就能够达到目的，因为对HTTP协议还算是比较熟悉，所以我的分析应该是没错，如果是在.net中，我会毫不犹豫地利用 WebHttpRequest（）进行请求的封装，通过设置Range字段来实现上述的功能，但是，问题是在静态页面的JS里面利用 XMLHttpRequest来实现，就有一定的难度了，毕竟从来没有接触过。查阅了大量的资料后发现，在XMLHttpRequest里面确实可以设置 SetHeader（），最终决定使用Prototype.js里面现成的封装来实现，具体实现如下&amp;#8212;&amp;#8212;&lt;/p&gt; &lt;p&gt;&amp;lt;script language="javascript"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //alert($("Shadow").innerHTML);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var myarray = new Array();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; myarray.push("Range");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; myarray.push("bytes=0-");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; myarray.push("Pragma");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; myarray.push("no-cache");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; myarray.push("Cache-Control");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; myarray.push("no-cache");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; alert(myarray[1].toString());&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; function myAJAX(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new Ajax.Request('replace.php', {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; method:'get',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; requestHeaders:myarray,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; onSuccess: function(transport){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var json = transport.responseText;//.evalJSON();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; alert(json);//.a);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //var data = '{ "name": "Violet", "occupation": "character" }'.evalJSON();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //alert(data.name);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/p&gt; &lt;p&gt;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/script&amp;gt;&lt;/p&gt; &lt;p&gt;为了测试，我使用Array.push()方法建立数组，没有直接初始化数组，一段儿测试代码大家将就看看，我说一下比较重要的几点：&lt;/p&gt; &lt;p&gt;1、Prototype里面RequestHeaders是一个数组，作为参数的内容必须是个数组；&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2、Prototype里面这个参数是可选得；&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3、Prototype里调用Ajax.Request()的时候加参数的方法和其他参数一样&amp;#8212;&amp;#8212;&amp;#8220;requestHeaders:myarray,&amp;#8221;参数用逗号分割。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4、Prototype里设置分段的方法如下&amp;#8212;&amp;#8212;&lt;br /&gt;Range头域可以请求实体的一个或者多个子范围。例如，&lt;br /&gt;表示头500个字节：bytes=0-499&lt;br /&gt;表示第二个500字节：bytes=500-999&lt;br /&gt;表示最后500个字节：bytes=-500&lt;br /&gt;表示500字节以后的范围：bytes=500-&lt;br /&gt;第一个和最后一个字节：bytes=0-0,-1&lt;br /&gt;同时指定几个范围：bytes=500-600,601-999&lt;/p&gt; &lt;p&gt;GEThttp://download.microtool.de:80/somedata.exe&lt;br /&gt;Host:download.microtool.de&lt;br /&gt;Accept:*/*&lt;br /&gt;Pragma:no-cache&lt;br /&gt;Cache-Control:no-cache&lt;br /&gt;Referer:http://download.microtool.de/&lt;br /&gt;User-Agent:Mozilla/4.04[en](Win95;I;Nav)&lt;br /&gt;Range:bytes=554554-&lt;/p&gt; &lt;p&gt;&lt;strong&gt;以上是一个测试的头，注意Range字段！&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;前段时间跳槽了，所以很久没来写文章，现在压力很大啊，感觉这么大个项目自己要亲自去设计，还是蛮有压力的，只能努力工作、祝自己好运了！在工作中如果发现什么觉得有价值的技巧，我会在这里跟大家进行分享。&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/niuniu502/aggbug/2184434.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/niuniu502/archive/2011/09/21/2184434.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
