代码改变世界

有了WCF,Socket是否已人老珠黄?

2010-12-25 16:58  田志良  阅读(...)  评论(... 编辑 收藏

1. Socket相关背景    

  Socket,中文译为“套接字”,最早在UNIX中引入并得到广泛应用,后来微软在设计Windows时引入了UNIX中的这个概念和相应的设计理念,并针对Windows的特性略作调整,形成了Windows平台上的Socket,简称为“WinSock”,并为开发者提供了一整套的API,称为“Windows WinSock Win32 API ”。

  WinSock经历了两个版本,Windows Sockets 2是目前用得最多的版本(参看 http://en.wikipedia.org/wiki/Winsock )。     

图 1所示为.NET平台下网络应用程序的层次架构:

      图 1
  WinSock在底层使用一个运行于操作系统核心的系统驱动(Windows Sockets Knernel-mode Driver)tcpip.SYS,由它们负责管理网络连接和缓冲管理。还有另一个驱动Afd.sys(Ancillary Function Driver for WinSock)则用于支持基于 window socket的应用程序,比如ftp、telnet等,被称为“ Windows NT 套接字驱动程序 ”。

  早期的Windows开发者,需要使用C/C++去调用WinSock,比如MFC就提供了一个“CSocket”类封装底层的Socket。.NET也提供了一组类来封装WinSock Win32 API,这些类集中于System.Net这一命名空间中,其中的核心类型就是Socket。Socket类是对WinSock API一个很浅的封装,拥有不少方法直接对应于WinSock中的C/C++函数,比如Poll、Select、IOControl等。

  Socket有一个Handle属性,它引用位于操作系统核心的Socket核心对象。Socket提供了众多的属性,还提供了SetSocketOption方法来设置各种选项,对.NET网络应用程序的数据通讯进行“微调”。Socket的功能出奇地强大,在.NET平台上,它支持以下四种典型的编程模式:

  (1)居于阻塞模式的Socket编程(单线程或多线程的),每个线程处理一个客户端连接 

  (2)“非阻塞”模式的Socket编程,这是早期UNIX为提升网络应用程序性能而采用的编程模式,出于兼容和方便移植原有程序的目的而保留,建议新开发的.NET网络程序不要再使用。

  (3)使用IAsyncResult的异步编程模式:Socket类提供有一堆的“BeginXXX/EndXXX”方法实现异步Socket编程,使用线程池中的线程完成工作,性能较好。

  (4)使用EAP的异步编程模式:Socket类提供了“另一堆”以“Async”结尾的方法,在底层使用Windows操作系统的Completion Port(完成端口)和Overlapped I/O mechanism(重叠输入/输出机制),可以提供“最高”的性能。


2. 有了WCF,Socket是否已人老珠黄?     

  基于Socket开发网络应用程序已经有很多年的历史了,现在的新技术层出不穷,在.NET平台之上,WCF大有“一统江湖”的势头,Socket是否真的“人老珠黄”?    

  请看图 2所示的多层“松花蛋”:

  
                        图 2
  图 2说明,WCF与WinSocket等底层技术之间实际上是一种“包含”关系,每一层都在下一层所提供服务的基础上,又扩充了新的功能,越外层的应用程序,可以使用的功能往往越多,开发效率往往也会更高。WCF在WinSocket的基础之上扩充了大量的功能,使用它可以很高效地开发网络应用程序,尤其非常适合于开发基于SOA的分布式软件系统,但这并不是说它可以完全把Socket打入冷宫。在不少场合,抛弃WCF那庞大的框架,直接使用Socket更合适:    

  (1)需要实现自己的通讯协议的场合(比如你要架设一个网络游戏服务器)。    

  (2)你开发的系统需要实现“一问一答”的“交互式”运行模式。    

  (3)你希望能全面控制你的网络应用程序的“每个方面”,不想花时间去理解WCF那个复杂无比的内部架构。    

  (4)你的网络应用程序应用背景非常单一与明确,比如就解决一个问题:定期将分布于多台计算机上的数据文件上传“汇总”到一台中心服务器上。    

  (5)……    

  如果需要基于各种标准协议(比如WS-*等)开发SOA的分布式软件系统,再使用Socket就不合适了,那会大大地增加开发的工作量和难度,WCF更适合于解决这个问题。在实际开发中,我们还可以混用WCF和Socket。比如我们可以基于WCF开发P2P的应用程序,使用NetPeerTcpBinding在P2P节点间“广播消息”,然后,在两个P2P节点之间直接使用Socket“私下”里传送一个“秘密”文件。