有了WCF,Socket是否已人老珠黄?
2010-12-25 16:58 by 田志良, 1802 visits, 收藏, 编辑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平台下网络应用程序的层次架构:
![](http://image48.360doc.cn/DownloadImg/2012/01/2204/21001419_1.gif)
图 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所示的多层“松花蛋”:
![](http://image48.360doc.cn/DownloadImg/2012/01/2204/21001419_2.gif)
图 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“私下”里传送一个“秘密”文件。
#1楼 韦恩卑鄙 v-zhewg @waynebaby 2011-01-06 14:55
(1)需要实现自己的通讯协议的场合(比如你要架设一个网络游戏服务器)。WCF序列化器你可以自己实现一个。
(2)你开发的系统需要实现“一问一答”的“交互式”运行模式。
全双工WCF也不难
(3)你希望能全面控制你的网络应用程序的“每个方面”,不想花时间去理解WCF那个复杂无比的内部架构。
往往不想花时间去理解wcf内部结构的人也写不出什么好的“每个方面”
(4)你的网络应用程序应用背景非常单一与明确,比如就解决一个问题:定期将分布于多台计算机上的数据文件上传“汇总”到一台中心服务器上。
简单也有简单的做法,
.net4的wcf server就可以用http put。
客户端嘛。。客户端当然用webrequest
System.Net.WebClient.UploadFile()就可以了。。。
socket 能不用,尽量不用。
#2楼[楼主] 田志良 2011-01-06 15:03
@韦恩卑鄙 v-zhewg @waynebaby从效率上将,Socket无疑是最好的。在很多方面,Socket仍然发挥了非常重要的作用,比如说,实现网络视频聊天,客户端用PHP+Flex,你服务端用什么通信?WCF?那是不可能实现的,只能用Socket。
#3楼 韦恩卑鄙 v-zhewg @waynebaby 2011-01-06 15:28
你一定要用 flex是没办法的 ,因为flash是个土鳖啊
sl就可以。
wcf支持打开的流传播。
一个调用中的参数可以是一个IStream,这个stream eof之前这个链接一直alive,调用一直不结束。
实现聊天神马的是如何实现和管理IStream这一个问题了
#4楼 韦恩卑鄙 v-zhewg @waynebaby 2011-01-06 15:35
另外 如果你comet理解得好, 何妨用flash开两个 Put/Get http流呢?restful 的视频聊天室用WCF实现
并不是不可能,只有敢不敢想。
#5楼[楼主] 田志良 2011-01-07 10:49
@韦恩卑鄙 v-zhewg @waynebaby呵呵,看得出来你对WCF有很深的理解啊,我最近也在看WCF,以后要向你多多请教啊。最近完成了一个网络视频聊天项目,那个项目就是用Socket来实现的,Socket效率很高,但开发周期比较长。
#6楼 Artech 2011-01-11 22:50
WCF和Socket其实没有太多可比性,应用目标范围不同,根本谈不上WCF替换Socket的说法。