原始码下载: MutualUdpClientSample_jb51net.rar
在开发与远程设备通讯的系统时,为了提高数据传输的效率,常常会选择UDP这个通讯协议来作为数据传输的媒介。而 .NET framework中所提供的UdpClient对象,可以帮助开发人员依照系统需求开启UDP套接字点,快速建立UDP联机来提供与远程设备通讯的功能。
这个系统架构下当增加一个不同种类的远程设备时,必须要提供一个不同的UDP套接字点,才能用来提供与不同种类远程设备通讯的功能,在远程设备种类越来越多时,系统所需要的UDP套接字点就会依照远程设备种类而增加。
在远程设备种类越来越多的情景中,为了网络管理考虑会限制系统与远程设备通讯时,必须统一使用同一个UDP套接字点来与远程设备通讯,再由封包内容、或是IP地址去判断实际连接的远程设备为何。
有涉略过Design pattern的开发人员,在遇到资源对象只能有一个实体的情景,会想到套用Singleton Pattern来提供资源对象共享的功能。系统中UdpClient对象所开启的UDP套接字点,就是属于这种只能由一个对象所开启的资源,这个情景中在UdpClient对象上套用Singleton Pattern看起来会是个不错的选择。
将Singleton Pattern套用在系统内所使用的UdpClient物件上,可以写出上列的程序代码,系统内所使用的UdpClient对象都是取用到系统内一个静态存放的共享UdpClient对象。这段程序代码内容可以通过编译程序的检查,并且在执行时也不会出现SocketException的例外通知,因为套用Singleton Pattern让系统内只会开启UDP套接字点一次。
但进阶一点去思考UdpClient对象的封包接收功能,UdpClient对象中提供Receive方法来等待、接收远程设备传送的数据封包,收到数据封包之后再次执行Receive方法会继续等待、接收下一个数据封包。也就是说一个远程设备传送的数据封包,UdpClient只能透过Receive方法取得一次,在系统内共享同UdpClient对象,没有办法共享Receive方法所取得的数据封包。
观察上列范例的执行结果,可以发现在范例中由transmiter所传送的资料封包,在被UdpClientA透过Receive方法接收之后,UdpClientB无法接收到这个远程传送的数据封包,这也就验证范例中将Singleton Pattern套用在系统内所使用UdpClient上的方式,会发生了无法共享数据封包的问题。
为了提供系统使用同一个UDP套接字点来与远程设备通讯,再由封包内容、或是IP地址去判断实际连接的远程设备为何的功能。笔者设计一个名为MutualUdpClient的解决方案,用来在系统内共享UDP通讯联机并且共享远程设备传送的数据封包。
在MutualUdpClient这个解决方案中,套用先前部落格中所发表的Singleton Pool模式,套用这个模式让系统能够共享UdpClient联机,并且在有系统对象使用UdpClient联机时就开启共享UDP通讯联机,而在所有系统对象都不需要使用UdpClient联机才真正去关闭这个共享的UDP通讯联机。
。
套用Singleton Pool模式解决了共享UdpClient联机的功能,接着在MutualUdpClient这个解决方案中,为了共享远程设备传送的数据封包,在UdpClient与MutualUdpClient之间加入了一个RouteUdpClient对象。
RouteUdpClient对象是一个主动式的对象,在被建立之后会开启一条独立的线程,不断的接收UdpClient所接收到的数据封包,并且将接收到数据封包透过事件的方式通知每个MutualUdpClient,经由这样的流程就可以将远程设备所传送的数据封包,在每个MutualUdpClient之间共享。
而MutualUdpC