八月 27, 2007

以 Cassini 来宿主 ASP. NET 客户端

发布日期: 11/16/2004 | 更新日期: 11/16/2004

Dino Esposito

下载本文代码: CuttingEdge0301.exe (107KB)

*

本页内容
宿主 ADO.NET 运行库 宿主 ADO.NET 运行库
ApplicationHost 类 ApplicationHost 类
示例 ADO.NET 主机 示例 ADO.NET 主机
Cassini 个人 Web 服务器 Cassini 个人 Web 服务器
CD 上的 Web 站点 CD 上的 Web 站点
小结 小结

早在 2000 年 9 月和 10 月发行的 MSDN Magazine 中,我讲述了如何构建 ASP 应用程序的客户端环境;也就是运行 ASP 网页的无服务器环境(参见 前沿技术:A Client-side Environment for ASP Pages前沿技术:A Client-side Environment for ASP Pages art 2)。这些专栏的灵感源自下面的情况。


设您的一个客户需要利用一张 CD 来在线发布某些内容,例如,百科全书、黄页或文档集。客户需要在 CD
内包含一个查看器应用程序和一种灵活的软件体系结构来传送内容。另外,除了有处理器最低性能和使用最新版本的 Windows 要求外,客户希望 CD
没有什么特殊的系统要求,从而方便用户使用。这意味着最终的应用程序不应依赖于国内版本 Windows 中包括的 Microsoft
Internet 信息服务 (IIS) 或个人 Web 服务器。它应在纯粹的、无服务器的环境下离线运行。

在很多情况下,客户有现成的
在线内容 Web 站点。在其它情况下,作为项目的一部分,她计划为在线内容创建 Web 站点。在这种情况下,利用 ASP 或 ADO.NET
来做这项工作是很明智的选择,因为它们非常灵活并且功能强大,可使您快速、有效地构建查看器应用程序。但是自定义应用中果真能够宿主 ASP 或
ADO.NET 吗?

大约三年前当我第一次探讨这个问题时,ADO.NET 还没有发布,只是谣传有一种暂定被称为 ASP+
的东西,这种东西很炫,并且不久即将发行。那时,没有可用来在 IIS 之外以离线方式呈现 ASP 页的工具。更糟糕的是,设计 ASP
并不能轻松地完成这样的宿主操作。因此我提出一种由两部分构成的 ASP 模拟器:一种专用的浏览器以及一个 ASP
服务器模块。构建的浏览器用来截取任何形式的提交与 URL 请求,并且将它们重定向到我自己的 ASP 服务器模块。反过来,ASP
服务器将从磁盘加载资源,解析其内容,从而动态生成 HTML 代码。该浏览器还负责利用与各种响应、请求和服务器 ASP
对象几乎完全相同的编程接口来实例化与初始化伪对象。图 1 概括了总体体系结构。

MIissues0301cuttingedgefig01

图 1 离线服务器

虽然不是理想的解决方案,但它还是满足了客户的期待,并整合成一种较大型的产品,今天仍然能够使很多专业人士使用在线和离线的内容。根据从这些专栏发布起我获得的反馈信息可以判断出,很多开发人员都面临过类似的挑战。


个月后,Microsoft 发布了第一个 beta 版的 ADO.NET,我思考着利用该新产品重新访问我的解决方案。ADO.NET
的设计是模块化的,所以很适合于宿主在外部应用中,包括 IIS 自身。但是,能够在自定义应用程序中宿主 ADO.NET 并不等于构建了一种由
CD 提供的离线 Web 浏览器的现成解决方案。在自定义应用程序中宿主 ADO.NET 运行库引擎仅是离线提供动态内容的第一步。如果看看图 1
中所示的体系结构您就会发现,它基于两个不同的组件 — 一个还接受用户输入的请求处理器和一个生成实际 HTML 代码的 ASP 源处理器。宿主
ADO.NET 引擎只是取代了图 1 中的 ASP 服务器模块。实际上,您需要更多的东西 — 在理想情况下,需要的是一个浏览器和一个嵌入的
Web 服务器。

ADO.NET Cassini 示例 Web 服务器(参见http://www.asp.net/Projects/Cassini/Download
是一种可以集成、部署解决方案的压缩、本地 Web 服务器。Cassini 采用 ADO.NET 宿主
API(System.Web.Hosting 命名空间)来创建简单的托管 Web 服务器。套接字连接是通过 System.Net API
来处理的。可从 Microsoft 获得 Cassini 的源代码。图 2 显示了基于 Cassini 的离线 Web
应用程序的典型体系结构。您可以看到,整个方案就像是一种基于 Internet 的典型 Web 应用程序,但是更为简单。很显然,Cassini
既不是 IIS 的完全代替物,也不是 Microsoft 版的开放源代码 Web 服务器。Cassini 是本地的 Web
服务器,用来处理对本地文件夹的本地调用。我将回顾一下 Cassini 组件,然后为您说明如何在 CD 上部署 Web 站点,并以此作为结束。

MIissues0301cuttingedgefig02

图 2 Cassini Web 应用程序


宿主 ADO.NET 运行库

ADO.NET 应用程序并不要求将 IIS 作为主机模块。事实上,ADO.NET 甚至不要求用 Web 服务器来运行。它公开了一个任何调用方都能使用的尽人皆知的接口,连接并要求内部的 HTTP 管道处理请求。

宿
主 ADO.NET 引擎时,两个类起着重要的作用 — ttpRuntime 和
ApplicationHost。前者是对象的管道的入口点,它更像一条装配链,可以将 .aspx 资源的原始 HTTP 请求转变为全新的
HTML 文本。后者使得客户端应用程序宿主 ADO.NET 引擎成为可能。ApplicationHost 类负责创建主机进程中的
AppDomain,该进程将处理新应用程序的所有传入请求。

Tim Ewald 和 Keith Brown 在他们的文章“HTTP Pipelines: Securely Implement Processing, Filtering, and Content Redirection with HTTP Pipelines in ADO.NET”(MSDN 杂志
2002 年 9 月刊)中全面讲述了 HttpRuntime 类的内部组成。只在应用程序主机收到并预处理请求时,才使用 HttpRuntime
类。应用程序主机将所有请求信息打包到一个请求类中,该请求类派生于 HttpWorkerRequest 抽象类,或更可能派生于其名为
SimpleWorkerRequest 的标准实现类。在准备好使用请求类实例后,主机将处理权移交给 HttpRuntime,调用其
ProcessRequest 静态方法,如下列代码所示:

SimpleWorkerRequest req;req = new SimpleWorkerRequest(aspx, null, Console.Out); HttpRuntime.ProcessRequest(req);  

前面的代码片断显示了启动对 ADO.NET 网页进行处理的核心代码。该代码的执行由通过 ApplicationHost
创建的主机类的某个特殊方法来控制。稍后我将回到该主题。现在,绝对可以说,SimpleWorkerRequest 的构造函数根据 ASPX
资源的虚拟路径进行处理、采用一个可选的查询字符串,并采用文本编写器对象作为输出。您可以使用流编写器对象(而不是标准输出控制台)将 HTML
代码保存到磁盘。

返回页首返回页首


ApplicationHost 类


机和 ADO.NET HTTP 运行库之间的交互是由名为 ApplicationHost 的特定 Microsoft .NET
Framework 类来控制的。从 ADO.NET HTTP 运行库的角度来看,主机只是调用方 — 即创建了当前的 AppDomain
并且通过调用 ProcessRequest 方法为特定的请求提供服务的模块。ADO.NET HTTP 运行库和主机之间的接口都由
ApplicationHost 类的操作来完成。HTTP 运行库全然没有调用方的特性 — 而完全是一个像 IIS 一样的 Web
服务器、一个像 Cassini 一样的的本地 Web 服务器,或者甚至就是一个片刻就可以创建的简单应用程序。ADO.NET 可以为调用
HttpRuntimeProcessRequest 并传递正确信息的任何模块提供服务。图 3 说明了 ADO.NET HTTP
运行库和其它部分的关系。

MIissues0301cuttingedgefig03

图 3 ADO.NET 与整个系统


ADO.NET 宿主在应用程序中的第一步就是创建新的应用程序主机。这可以通过调用 ApplicationHost 类的
CreateApplicationHost 静态方法来完成。CreateApplicationHost 在调用方进程中创建新的
AppDomain。之所以需要新的 AppDomain 是因为 ADO.NET 要依靠一些设置,这些设置只能在 AppDomain
级进行设置,并且某些设置只能在创建 AppDomain
之前进行。这些设置的一部分是投影复制缓存位置的应用程序基本路径和目录。CreateApplicationHost
需要一个虚拟文件夹才能工作,这意味着在第一次访问某个新的虚拟文件夹时就会创建一个新主机并随后创建新的 AppDomain。(注意像
Cassini 这样的简单 Web 服务器一次只需要一个虚拟文件夹,但这只是一种特殊情况。)

在创建主机接口对象后,典型的主机应用程序就开始监听请求。如果主机的工作方式与 Web 服务器的相同,它就要通过端口 80 开始监听传入的消息;否则它可以是您指定的任何端口。然后将请求打包到请求类中,并传递给 ADO.NET 运行库。

HttpRuntime.ProcessRequest
方法通过对象的管道路由 Request 对象。在通道末端会出现一个新对象 — 就是动态创建类的一个实例,该类是 Page
类的继承类,该实例表示被请求的 .aspx 页。要结束该请求,HTTP 运行库要调用 Page 类的ProcessRequest 方法。该页的
ProcessRequest 方法执行 Page 对象的大量任务,每项任务都以事件作为信号。通过利用 runat=server
属性集来为该页的每个组成元素创建服务器控件实例,对该页进行首次初始化。接着,ADO.NET
代码加载该页的视图状态,并将它与发送的数据(如文本框和复选框的值)合并。最后,运行库执行客户请求的任何服务器代码(大部分为回发事件),保存视图状
态,并将 HTML 写到输出编写器中。

CreateApplicationHost 静态方法是 ApplicationHost 类的唯一成员。它的 C# 原型如下所示:

public static object CreateApplicationHost(   Type hostType,   string virtualDir,   string physicalDir);

以上代码片断所示的 virtualDir 参数表示所创建的应用域的虚拟目录,而 physicalDir
参数表示此虚拟路径后的文件系统路径 — 被请求的 .aspx 文件必须从该磁盘文件夹为该 Web 应用程序进行加载。这些信息都与域相关,并由
ADO.NET 工厂对象用来创建 HttpApplication 对象 (global.asax) 和网页对象 (.aspx)。

CreateApplicationHost
的第一个参数是类型对象,它的赋值是应用程序定义的主机类的类型。这种方法返回用户提供的类的实例,该类用来连接主机程序的默认 AppDomain
和新近创建的 AppDomain(参见图 4)。主机类型对象是类似服务器应用程序的核心代码和目标
AppDomain(CreateApplicationHost 先前创建)中 ADO.NET HTTP
运行库之间的一种代理。主机可执行程序可能需要配置、启动与终止特定的 Web 应用,因此在 AppDomain
中需要有一个专门的对应部分。反过来,主机类型包括监听 HTTP 请求端口的方法。当请求到达时,将创建 SimpleWorkerRequest
对象并传送给 HttpRuntime。

MIissues0301cuttingedgefig04

图 4 默认 AppDomain


求对象是在同一 AppDomain 中创建的,实际上,该 AppDomain 将为请求提供服务。HttpWorkerRequest
是抽象基类,它定义了 ADO.NET 用来进行处理请求的所有属性和方法。SimpleWorkerRequest 是基类的简单实现,可以为
ADO.NET 运行库提供诸如被请求的 URL 和查询字符串等最低限度的信息。它还可以将 ADO.NET
输出接收到流编写器对象。如果您认为需要更多的预处理功能(如像解析报头和发送的数据),那么您可以扩展 SimpleWorkerRequest
并适当覆盖 HttpWorkerRequest 方法。(查看 Cassini 源代码获得扩展 SimpleWorkerRequest
的类的具体示例。)

返回页首返回页首


示例 ADO.NET 主机


许多东西支持 ADO.NET ËÞÖ÷。我们来编写一些代码以说明如何将 ADO.NET 宿主在一个 Windows 窗体应用程序中。思路是利用
ADO.NET 来为该程序的各种功能生成帮助页。示例应用程序的用户输入关键字,并可以迅速在 HTML 页中显示出来。HTML 页由
ADO.NET 页动态生成,该页对应所需的帮助。

图 5
显示了 Windows 窗体应用程序的核心代码。加载时,窗体初始化了应用程序主机。虚拟根文件夹称为 /dino;其文件位于当前文件夹的
Help 子目录中。注意 /dino 只是一个名称,所以不需要为之创建文件系统目录或 IIS
虚拟文件夹。物理路径必须存在,否则将会抛出“找不到文件”的异常。

主机类型是一个名为 MyAppHost 的类,其源代码如图 6
所示。MyHostClass 只有一个方法,即
CreateHtmlPage。主机类成员的数量和原型完全由您决定。最要紧的是您要设计一个可以反映您想要做的事情的编程接口。在这种情况下,最终目标
相当简单 — 只是接受 ASPX 文件,然后转化成 HTML。SimpleWorkerRequest
对象合乎所愿,其构造函数的原型正是所需要的。

第一个参数是要处理的 ASPX
文件的名称。第二个参数是可选的查询字符串。注意,如果您使用命令行参数的 URL,那么真实的文件名将是错误的。(在预处理该请求时,IIS 将
URL 与查询字符串分离开来。)SimpleWorkerRequest 类希望将 URL
和查询作为两个不同的实体进行接收。另外还要注意,必须删除初始的查询字符串字符。

最后,构造函数的第三个参数是可用来缓冲输出文本的流编
写器对象。ASPX 页通过 Response(更高级的方法,如
Page.Render)发出的所有内容都会收集在该编写器内。我使得编写器在某个临时 HTML 文件上工作,因此当关闭编写器时就会创建 HTML
文件。最后,嵌入的 WebBrowser ActiveX? 控件显示该页。

您可使用的 ADO.NET 功能没有限制 —
ADO.NET HTTP 运行库是驱动力。可以随意地使用配置文件、ADO.NET 适配器、视图状态、输出缓存、XML、HTTP
模块以及任何其它 ADO.NET 和 .NET Framework 所涉及的东西。另外,应用程序与 IIS 的状态无关。您可以保持 IIS
为运行状态或者甚至终止它 — 由示例应用程序宿主的 ADO.NET 运行库将不受影响。(IIS
只是另一种应用程序主机,尽管是一种特别丰富和复杂的主机。)

由于 ADO.NET 受到了保护,因此规定所需的程序集与
ADO.NET 中的完全相同。这意味着必须将包含主机类的程序集同时复制到 ADO.NET 主机应用程序目录和 ADO.NET 应用程序文件夹的
Bin 子目录中。另一种选择是将该程序集放入全局程序集缓存 (Global Assembly Cache,GAC) 中,就像在 Cassini
中一样。原因是两个模块都需要加载该主机类:该主机应用程序模拟 IIS 和被调用的 ADO.NET
辅助进程。两个可执行文件都要在各自的路径中为程序集找到主机类。对于主机应用程序来说,路径就是当前的文件夹;对于 ADO.NET
辅助进程来说,路径是包含 .aspx 页或 GAC 的文件夹的 Bin
子文件夹。正因为要在两个不同的地方才能找到主机类,所以强烈建议您在独立的程序集中对其进行编码。但是,在同一可执行文件中嵌入应用程序和主机类是合法
的,并且工作正常。例如,对于示例应用程序,您必须在与可执行文件相同的文件夹 (Folder\Bin\Release directory)
中备份 MyAppHost,第二个备份应该位于 Folder\Bin\Release\Help\Bin 文件夹(Bin 在 ASPX
文件之下,一般的 ADO.NET 应用程序需要这样做)。

返回页首返回页首


Cassini 个人 Web 服务器


够在用户应用程序中宿主 ADO.NET 可能并不像听起来那么令人兴奋。当然,您可以构建智能帮助系统,设计离线工具来将 Web
站点的网页预编译成 HTML。但是在无 IIS 的情况下,只通过 ADO.NET 宿主可以让您构建运行在本地机上的类似 Web
应用程序的无服务器应用程序吗?

如果您还不相信,那么想一想:如果 ADO.NET
页包含交互控件和回发功能,则将发生什么事情?我们回顾一下示例主机应用程序的这种情况。HTML 页是通过 WebBrowser 控件来显示的 —
Microsoft Internet Explorer 的浏览引擎的实例。浏览器总是通过端口 80 转发 HTTP POST
命令来处理链接上的点击。因为应用程序主机在端口 80 上没有激活的监听程序,所以将返回一个“page not
found”的错误。您需要在客户端顶部构建一个自定义层来截取并将回发信息重新定向到应用程序主机专用的 Request 对象。换句话说,实际利用
ADO.NET 宿主仅可以呈现静态的、只读网页。顺便说一句,这方面也被证明是最难克服的障碍,我以前在 2000 年 9
月的专栏中提到过。因为这是该难题的主要部分,因此仅通过 ADO.NET 宿主不足以构建真正的、无服务器环境以离线使用 Web
站点。这需要配备一个小型 Web 服务器,服务器能够理解浏览器需要什么。Cassini 示例 Web 服务器是完成这项任务的理想工具。

MIissues0301cuttingedgefig07

图 7 启动 Cassini

Cassini
Web 服务器是一种名为 cassiniwebserver.exe 的 Windows
窗体应用程序。通过指定要监听的端口号、要监控的虚拟路径以及其背后的物理路径来启动 Web 服务器。通过图 7 中所示的窗体启动
Cassini。注意,Cassini 一次只能处理一个虚拟文件夹,并且只能接收通过 localhost 产生的请求。这正是您在诸如 CD 或
DVD 等离线媒体上部署现有 Web 站点所需要的。Cassini 是一个托管应用程序,它的可执行文件占用不超过 70KB。除了程序
cassiniwebserver.exe,您还需要考虑应用程序主机 DLL —
assini.dll。必须要利用下面的命令行指令,将应用程序主机程序集保存在 GAC 中:

gacutil /i Cassini.dll

图 8 列出了构成 Cassini Web 服务器的应用程序主机的所有公共类。所有类都在 cassini.dll 程序集中编译。Server 类是主机可执行文件的入口点。其构造函数创建应用程序主机,将 Host 类指定为主机类型。

void CreateHost() {   m_host = (Host) ApplicationHost.CreateApplicationHost(            typeof(Host), vdirPath, filesPath);   m_host.Configure(this, port, vdirPath, filesPath,_aspnetPath);}

Server 类的实例在 Cassini 的 AppDomain 中创建,但 Host 对象却属于
AppDomain£¬创建它是为了处理 HTTP 请求。Server 对象还提供了一种公共 API 来启动、停止和配置 Web 服务器。Web
服务器 (cassiniwebserver.exe) 将该对象看作为它与 ADO.NET 后端的唯一接触点。

Host
类表示一个远程对象,并且继承了 MarshalByRefObject。远程对象是一个可从不同的 AppDomain 内调用的对象。Host
类负责打开指定端口上的套接字,并监听传入的数据包。当请求到达并被接收后,该类将创建一个新的 Connection 对象来处理该请求:

Connection conn =  new Connection(this, (Socket) acceptedSocket);conn.ProcessOneRequest();

Connection 类收到套接字,开始处理 HTTP 数据包。Connection 对象是主机和实际辅助请求间的主要媒介。它首先创建 Request 对象,然后请求该对象处理负载:

Request req = new Request(host, this);req.Process();

Request 对象派生于 SimpleWorkerRequest。它检查 HTTP
数据包,提取并预处理消息标题,并准备响应缓冲区。完成后,它只是将该请求发送给 ADO.NET HTTP 管道,以实际生成相应的 HTML
响应文本。ADO.NET 管道中的入口点是 HttpRuntime 对象的 ProcessRequest 方法。执行该请求时,ADO.NET
回调 Request 对象的几种方法。特别是,所有通过 Response
对象发送出去的数据都会引起对主机辅助请求的某个公共方法的调用。Cassini 的实际实现是利用 Request 类将这个响应数据传送给
Connection 对象的方法,反过来,该方法将通过打开的套接字和端口路由数据。正是因为这个原因,Connection 对象的实例将被传送给
Request 类的构造函数。

如果您考虑一下 Cassini 的体系结构并将它与图 4
进行比较,那么您一定会认为它是一种常用模式。Cassini 是构建无服务器 ADO.NET
应用程序的合适工具,因为它结合了两个重要功能:能够宿主 ADO.NET 来处理 ASPX 请求与一种简单的、本地 Web 服务器基础结构。利用
Cassini,您不需要自定义查看器顶部运行的代码,从而处理所有网页的回发信息。Cassini 就是看不见的链接,它现在使得在无 IIS
的情况下传送 CD 上的整个 Web 站点成为可能。

返回页首返回页首


CD 上的 Web 站点


第一次检查 Cassini 时,我采取了下列步骤来检验其有效性。首先,终止 IIS,启动 Cassini 可执行文件,如图 7
所示。注意:为了测试 Cassini,必须首先终止 IIS,否则将发生端口冲突。另外,Cassini 只能处理通过
http://localhost 的调用;您不能利用机器名(如 http://msdnmag)访问本地网页,也不能从远程计算机访问装有
Cassini 的机器上的 Web 页。

启动 Cassini 并终止 IIS 后,我打开了 Internet Explorer
并输入 http://localhost。出乎意料的是,我竟在没有 IIS 的情况下运行了基于 ADO.NET 的
localnet!不言而喻,如果网页包含到 Internet Web 站点的链接,那么,只要 Internet 连接可用,它们就将照常工作。


是,要成功地将 Web 站点打包到 CD
上,必须执行几项初步的检查。首先,确保网页内的所有链接或者与本地主机相关,或者明确的位于本地主机上。否则,会出现 HTTP 403
错误(禁止访问)。为了离线部署 Web 站点,将所有文件与 Cassini 可执行文件以及 .NET Framework
可重新发布的文件一同复制到存储媒介上。配置安装程序以复制 Web 站点树,并将 cassini.dll 安装到客户机的 GAC
上。另外,应启动 Cassini Web 服务器。还应检查 IIS 的安装程序,如果正在运行,则终止它。

如果您将 Cassini
用于离线的 Web 应用程序,最好完全禁用 IIS。附带说一句,这正是您试图构建 ADO.NET 页时 Web Matrix
所做的事情。Web Matrix 是支持社区的、免费 IDE,是专门为 ADO.NET 应用程序设计的(从 Microsoft 的 http://www.asp.net/webmatrix/download.aspx
处下载)。Web Matrix 带有 Cassini,但是,如果您能提供 IIS 虚拟文件夹,也可以使用 IIS。如果您选择使用
Cassini 作为 Web 服务器,那么 Web Matrix 将发出警告:它正准备终止 IIS。从这点来看,Web Matrix
的行为正如 ADO.NET 主机应该采取的行为。图 9 显示了可以在安装程序中用以终止 IIS、启动 Cassini,并打开本地主机根目录的代码。

返回页首返回页首


小结


第一个 beta 版的 .NET Framework 开始,System.Web.Hosting
命名空间就可以使用了。但要获得完整的文档还需要一段时间。ADO.NET
可由任一托管可执行文件宿主的事实是一个巨大的进步。只要非托管应用程序可以宿主 CLR,它们也就可以宿主 ADO.NET 运行库。这正是 IIS
用来为 ASPX 请求提供服务的 ADO.NET 辅助进程 spnet_wp.exe 所带来的一切,spnet_wp.exe 是一个
Win32 进程,但是它宿主公共语言运行库,随后又宿主 ADO.NET。另一方面,Cassini 是一种决定性的工具,它允许 ADO.NET
应用程序在无服务器的情况下离线运行。

将您的问题和评论发送给 Dino cutting@microsoft.com

Dino Esposito 是意大利罗马本部的讲师兼顾问。他是 Building Web Solutions with ASP.NET and ADO.NETApplied XML Programming for .NET 两本书的作者,这两本书均由 Microsoft Press 出版。Dino 大部分时间教授 ADO.NET、ADO.NET 和 XML 方面的课程。可以给 Dino 发送电子邮件 dinoe@wintellect.com

Powered by ScribeFire.

        F#(发音为F sharp)是一种基于OCaml的函数式程序设计语言,它由微软研究院设计。运行它所需的所有工具可从微软免费获得。

F#可以在.NET CLR中运行,这意味着它可用于现存的.NET项目。此外,它还可以利用所有其它.NET代码。它克服了函数式程序设计语言的传统弱点,如缺少库函数,使用工具和开发环境等。

F#语言可以独立使用,但也可以直接插入Visual Studio。F#程序设计语言以完成某个特定任务所用代码行数的高效性著称。同时,据报道它的运行速度与C#一样,对某些任务甚至比C#更快。

安装

为了安装F#,你需要下载安装包。不幸的是,微软的F#网站有点过时了。为了获得该软件的最新版本,可以到微软研究院下载处,然后搜索F#编译器。当前最新版本为2007年5月1日发布的F#1.9.1.9。安装过程和其它Windows 应用程序一样而且也十分简单。安装完成后,当你打开Visual Studio时,就会看到“F# Research Compiler with Visual Studio”已经添加进去。(如图A)。

图 A

F#程序设计言初(上)

Visual Studio

我们的第一个F# 项目

为了试验一下F# ,在Visual Studio中打开一个新项目。在“其它项目类型”中,将会看到“F# 项目”。目前这里只有模板(如图B),但是作为起步已经满足我们的要求。为新项目命名,单击“确定”。

图 B

F#程序设计言初(上)

F#模板

现在,我们有了一个空项目。与标准Windows 窗体或Web应用项目不同,F#模板不会创建一系列目录,默认文件,或任何其它类型的文件。添加一个新条目到模板中,选择“F#源文件”作为模板(如图C)。

图 C

F#程序设计言初(上)

F#源文件

你将会看到已经加入了一个新文件。打开该文件,将会显示F#模板中充满了作为简单指南的代码。

尽管本文只对F#作简单介绍,但我们将会看一段简单的代码:斐波那契数列生成器,这是一个了解函数式编程的相当标准的基本程序。

我们将会使用斐波那契数列的标准定义。fib函数代码来自F#手册。下面是我们的简短小程序(列表A):

列表 A

// A Fibonacci Sequence generator

//Get the command line arguement as an integer type (Int32)
letfib_number=int_of_string (System.Environment.GetCommandLineArgs().GetValue(1).ToString());

//Set the label “fib” to be equal to a Fibonacci Sequence function
let rec fib n =
if n < 2 then 1 else fib (n-2) + fib(n-1);;

//Print the input number and the Fibonacci sequence
Printf.printf “nThe Fibonacci value of %u is: %un” fib_number (fib fib_number);;
//Exit the program, returning a normal status code to the OS
exit 0;

程序的第一行是提取命令行参数数组的第二个元素(第一个元素是可执行名本身),并将该参数转化为一个整型数(F#是静态数据类型),然后将该值存储在名称为“fib_sequence”的符号中。

第二行定义一个名为“fib”的函数。如果输入n小于2,该函数输出数字1,否则返回参数分别为n-1与n-2的函数自身调用之和(“rec”属性表示该函数是一个递归函数)。

第三行使用我们熟悉的printf函数输出结果。最后,程序结束。

这段小程序演示了F#很多有趣的方面,如果你在Visual Studio中完成该应用程序将会对此有更深的了解(一定要指定一个用来生成斐波那契数列的整数型命令行参数)。


有趣的一点是懒惰计算法。懒惰计算法的思想是一个符号是在第一次使用时赋值,而不是在定义时赋值。单步跟踪代码(Visual
Studio中安F11键)查看“fib_number”显示尽管“fib_number”在程序的第一行就已经定义,但是直到通过调用printf函数
输出才对它进行了赋值。

本例中另一个值得注意的地方是递归的使用。此处通过使用一个递归函数,代码的行数变得很少。尽管本例可能对于较大的数不是很有效(堆栈使用会很大),但是在实现速度方面还有很多其它高效的方法,递归只是一种可以解决许多问题的技术,但并不一定是最好的。

最后一点是从F#可以很简单的访问.NET框架。System.Environment.GetCommandLineArgs()方法的调用很好的完成了我们期望的工作。

通过使用ToString方法将结果对象类型投影到一个字符串,然后通过int_of_string函数投影到一个F# 的int32类型,这些都很好的完成了我们需要的工作。

虽然F#与C#、Java和许多其它编译语言一样都是静态类型,但是它仍旧可以以像Perl语言的方式执行类型引用。

结束语

F#是.NET世界中一种相当独特的语言。它可以被.NET中的任意其它代码编译和调用(也可以调用其它代码)。同时,它还提供了一个交互式运行时环境,该环境已逐行解释的方式工作。

它和大多其它编译语言一样拥有静态类型,但是它可以像很多动态或解释语言一样执行类型引用。它还可以面向对象(但并不是强制的)。

F#文档本身仍旧很少,编写上面的简单程序时,为了找到如何将第一行返回的对象投影成一个整型花费了我很多时间。据说,OCaml语言拥有大量可用于F# 的文档。

按照来自F#网站的消息,F#并没有偏离OCaml很远,但是二者之间肯定有所区别。Visual Studio的集成性也是很好的一点。

因此,前进吧,试一下F#!它是免费的而且你还可以学到一些新的编码技术,即使你已决定F#不适合你。

Powered by ScribeFire.

八月 24, 2007
jap-logo.pngJAP是一款来自德国的基于Java的开源网络代理软件,以速度快、匿名而著称。

之前我使用Tor的途中,越来越频繁的“连接超时”了让我受不了。因此我决心换成JAP以一劳永逸。

JAP的安装与配置与装Tor时类似,因此写出来与大家一同分享,给所有想置身于墙外的朋友。

安装Java运行环境

因为JAP是基于Java的, 所以我们得先安装JRE,这里推荐最新的sun-java6-jre,据说速度有了不少提升:

sudo apt-get install sun-java6-jre

安装好后,就不用理会它了,一切是自动配置

下载并运行JAP

下载jar软件包,保存至任意位置,你可以给它建立一个文件夹:JAP.jar

如果你对它的源代码感兴趣,请下载这个: jap.src.tgz

下载好JAP.jar,默认情况是用“归档管理器”打开的,我们得改一下,让它直接双击就可以运行。右键点击JAP.jar选择“属性”,在“打开方式”标签里,选择“Sun java 6 runtime”,设置好后,以后就直接双击即可运行。

jap-open-method.jpg

配置JAP

第一次运行JAP需要针对语言、端口、匿名警告等做一些简单配置:

第一步是设置语言,不用多说了,选择English即可。选择好后可能软件会关闭重启,我这里要自己手动再次启动它。

然后再会出现代理的IP和端口,保持原有的127.0.0.1和4001不变,直接Next好了。

需要注意的是这步,出现“匿名警告”的设置,一般选择最后的绿色一项,即当你处于非匿名状态浏览一些你指定的网站时,给予警告和阻止。前提是在JAP的主界面,在“Anonymity”这个框里,你勾了“on”。

jap-warning-1.jpg

设置好以后,可能还需要启动一次JAP,然后它会自动寻找代理,找到以后,你就可以使用127.0.0.1:4001这个代理了。只管JAP开着就可以了,可能比Tor占的资源多多了。呵呵。

主界面如下:

jap-main.jpg

如果闲窗体太大碍事,可以点击下面的第一个按钮,可以使JAP缩小到屏幕的一角,只显示当前通过这个代理的流量和匿名状态,非常不错。

jap-small.jpg

为Firefox装备FoxyProxy

到这个网页,为Firefox安装这个强大的代替管理插件:

http://addons.mozine.cn/addon.php?id=259

安装好重启Firefox以后,会在下面的状态栏显示出来,直接双击打开它。

工作模式是默认的“使用基于其预定义模板的代理服务器”,不要改它。

然后点击“新建代理服务器”, 在常规标签点自己写个名称,如JAP;在“代理服务器细节”上,按如下填好:

foxyproxy-proxy.jpg\

比较重要的是“模板”那里,在这里加上墙外的网站,你就可以做到访问墙内的网站不用代理,访问墙外的网站,自动用代理,完全不用切换。

这里权举一例,其他大家可以根据自己的需要加:

如“维基百科”,除了加入首页URL──http://zh.wikipedia.org/以外,还得在最后面在一个通配符──*,这样除首页能访
问外,其他内文也能访问了。同理,如果想要访问blogger,只要加入“http://*.blogspot.com”就可以了。

foxyproxy-wikipedia.jpg

设置好以后,确认你的JAP正在某个角落呆着,访问那些被封的网站,这时,你已经在墙外啦~

不用担心像Tor一样出现“连接超时”,JAP的速度和稳定性都不错,至少在我这里是这样。

有时你想临时访问一个网站,却又懒得加模版怎么办?那么右键点击FoxyProxy这个图标,选择:为全部URLs启用代理服务器”JAP”。这样访问所有的网站都是经过JAP的了。

个人还是建议把一次性把自己常访问的墙外网站都加入模版里,以后打开Firefox前,只要双击JAP.jar,仿佛置身于墙外。哈哈!

Powered by ScribeFire.

八月 20, 2007

94个比付费软件更好的免费软件

  August 18, 2007 – 10:26 am

原文地址:94 of the Best Free Software Applications that are Better than Purchased Software

最好的网页浏览器

  • FireFox。FireFox是一款非常受欢迎的浏览器,它有比IE更高的安全性与用户可定制性,能自动升
    级,快速标签浏览,更好的隐私保密设置,一个整合的搜索框,还有书签,而这些仅仅只是Firefox最基本的功能,你还可以下载不计其数的插件来扩展它的
    功能。FireFox主页及下载地址:http://www.mozilla.com/firefox/
  • Opera。Opera是另一款非常有名的浏览器,它有许多与FireFox相同的功能,速度快,小巧是它的最大特点。http://www.opera.com/

最好的BT下载客户端

  • Azureus是一款使用Java语言编写的BT下载客户端,支持多任务下载,(种子或者普通文件)队列下载
    /优先权下载,用户设置开始/停止引晶,以及快速获取大量种子资料的功能。Acureus使用内惬式Tracker,让你管理自己的种子更容易。
    µTorrent是一款非常小巧且高效的BT下载客户端,支持频宽管理,排程, RSS自动下载,Mainline
    DHT(与BitComet兼容)。Azureus:http://azureus.sourceforge.net/
  • µTorrenthttp://www.utorrent.com/

最好的多协议公共下载软件

  • Shareaze是一款受评价极高的多协议P2P下载软件,支持Edonkey200,Gnetella,Gnetella2(G2)以及BitTorrent四种流行网络类型。Shareaza:http://www.shareaza.com/

最好的FTP客户端

两个最好的FTP客户端FileZilla与 SmartFTP都有着非常强大的功能。

最好的聊天软件

特别突出的两个聊天软件是 Gaim/Pidgin和Trillian,这两个都是多平台的,Gaim能同时登陆AIM、ICQ、MSN
Messenger、Yahoo!、IRC、Jabber、Gadu-Gadu、SILC、GroupWise
Messeger和Zephyr等平台,而Trillain是一款可以自己更换皮肤的多平台聊天软件,支持AIM、ICQ、MSN、Yahoo!
Messenger和IRC,Trillain同时还有很多其它同类软件所有没有的功能。

最好的AIM病毒查杀软件

AIM FIX就是为了用一款强大的清除工具来清除所有已知AIM病毒而设计的,

最好的电话软件

这些软件允许你免费与别人通话,你所需的仅仅只是一个耳机和一个麦克风,Skype具有超强的加密技术与较高的音质,除了Skype之外的一款替代品为Gizmo Project。

最好的下载软件

工作效率最高的几个下载软件莫过于Flash Get,Getright和Free Download Manager,它们都是多线程下载,下载速度可以比普通下载高100-600%,它们甚至能够修复已破损的下载。

最好的Gmail文件传输工具

这里有一个非常好的软件,它允许你将你的文件上传备份到你的Gmail的邮箱空间,它就是Gmail Drive。

最好的Email客户端

Mozilla的另一款经典软件,Thunderbird,它是一个全功能的电子邮件客户端,功能包括垃圾邮件过滤,反钓鱼保护,增强的电子安全氏族,并能自动更新,还有非常多的插件可供选择以增强它的功能。

最好的博客发布软件

w.blogger是一款非常好的博客工具,它仅仅只有一个模板和一个文章编辑器却能与很多不同类型的博客站协同工作,包括Blogger,并且它不像其它博客工具,它发表文章并不要求你的博客是建立在FTP空间上的。

最好的IRC客户端

除mIRC之外,其它受欢迎的IRC客户端有IceChat与HydraIRC。

最好的IRC扩展

NoNameScript是一个非常好的IRC插件,很值得在mIRC上安装。

最好的反间谍软件

Spybot、Ad-aware、WindowsDefender与Spyware
Blaster都是非常不错的反间谍软件,前三个软件都有自己特殊的功能,包括实时扫描、加密文件删除、历史痕迹清除等,而Spyware
Guard(像Anti-Virus)更多的是一款实时扫描工具,而Spyware
Blaster并不是一款扫描工具,但是它能阻止间谍软件安装到你的电脑,尽管这四个软件并不是100%有效,但我们还是推荐他们。

最好的杀毒软件

Grisoft出品的AVG是一款非常受欢迎的杀毒软件,它能自动升级、实时扫描以及邮件扫描。另一个非常好的软件是
AntiVirPersonalEdition
Classic,与前者的功能有很多类似,但要记住一点,免费软件与收费软件之间是有很大差距的。ClamWin也是非常好的杀毒软件之一,他是开源软件
ClamAV的一部分。

最好的防火墙软件

最好的防火墙软件莫过于ZoneAlarm,他非常适合初级用户,因为它简单;同时它也适合高级用户,因为它有更多的高级功能。

最好的Anti-Rootkit软件

AVG Anti-Rootkit能清理你系统中的隐藏程序和进程,安全检测和清除在您的计算机系统里隐藏的所有rootkit项目。

做好的诊断工具

Ultimate Boot CD是一款非常棒的系统引导工具,它能恢复已损坏的计算机,去已经在很多电脑与笔记本上使用过他了。

最好的磁盘清理工具

CCleaner,它清除了我以为已经通过Disk Cleaner清除掉了的15G未使用数据以及网络缓存。他能安全地清理磁盘并且能扫描垃圾注册表信息,加速你的计算机。他还能帮你完全清除上网时产生的Cookie,保护你的网站数据。

最好的文件删除软件

Eraser是一款Win系统上安全性那个非常高的先进软件,通过它详细且安全的选择系统,你能擦除或改写系统内的敏感信息 。

最好的文件加密软件

推荐的三款软件是GNU Privacy Gaurd、TrueCrypt、and Blowfish Advanced
CS。GNU是PGP的完美替代者,它是基于命令行操作的,并不适合初级用户,但是Blowfish Advanced
CS使用多重晕算法、以及非常有效率的数据压缩和安全钥匙处理对文件进行安全保护。TrueCrypt可以创建虚拟加密磁盘,或者加密整个磁盘和其它储存
器(如U盘),并且它是用双重密码保护,以防止他人破解你的密码。

最好的MD5码创建/校验器

这个开源软件时使用L. Peter Deutsch的
MD5码来进行MD5码计算,它使用最广的就是使用它来确定用户下载的文件是否被损坏,有很多网站在其下载页面提供MD5码,当你下载网文件后,使用
winMD5Sum从你下载的文件上提取MD5码,在与网页上提供的进行对比看是否相同,如果相同,则你下载的文件是完整正确的。

最好的文件解锁软件

Unlocker是Windows Explorer的拓展,它允许你通过简单的右键单击文件或文件夹来清除错误信息,如:删除问价或文件夹错误;不能删除该文件夹:它现在正在被使用!。

最好的图片处理软件

GIMP与Paint.NET
是最好的两个图片处理软件,GIMP更像Photoshop,它还有一个特别版本,看起来非常像Photoshop(为的是更好上手)。
Piant.NET是一款MS画图软件的完美替代者,除了画图软件有的功能之外,他还增加了很多Photoshop才有的功能。

最好的矢量图编辑软件

Inkscape 是一款开源的矢量图编辑软件,其功能像Illustrator、Freehand、CorelDraw或Xara X ,都是使用 W3C 可缩放矢量图形标准『Scalable Vector Graphics (SVG) 』

最好的图片查看/编辑软件

IrfanView
支持很多图片格式,并且通过插件,它还能用来视频、Flash以及一些音频文件。Picasa,他能编辑图片并能搜索计算机内存出的图片。另一款是
FastStone Image Viewer,它是一款非常快速、稳定、用户友好的图片查看、格式转换以及编辑软件。

最好的数字相册软件

InAlbum Lite 是一款非常容易使用的相册软件,通过它,你可以很轻易地将大量的相片制作成极好的幻灯片。

最好的3-D三维软件

Blender是最好的开源三维建模、动画、渲染、后期制作、交互式创作和回放软件。

最好的配色工具

Color Schemer ColorPix 是一款非常小巧的配色工具,他能对色彩进行非常精确的定位,并可以将其转换成很多种色彩格式。你还可以使用其内置的放大镜工具放大观看,它还可以在所有软件之上显示,当然,他还是一款免安装的绿色软件。

最好的虚拟磁盘工具

如果你想不使用CD或DVD就运行.ISO或者CD镜像,推荐你使用DAEMON Tools—一款免安装的工具。

最好的DVD解密器

就像其名字所告诉我们的,DVD
Decrypter允许你将DVD复制到你的磁盘里,并且将其转换成MPEG1(VCD)或者DivX格式,他还能通过”ISO模块“将镜像文件写如CD
或DVD。另一款软件是DVDFab HD Decrypter,他也能将DVD里的电影复制到磁盘里,并可以在赋值的同时清除所有保密措施(CSS,
RC, RCE, APS, UOPs and Sony ARccOS),当然它还支持HD-DVD他蓝光DVD(Blu-Ray)。

最好的DVD压缩软件

ratDVD 是一款功能齐全的DVD压缩软件,它能将DVD-9进行高度压缩,它能将整张DVD压缩至1.x GB左右的大小。

最好的CD/DVD烧录软件

CDBurnerXP Pro 是一款专业的CD/DVD烧录软件,并且支持ISO镜像创建功能,它运行非常快,并且拥有几乎所有你能想到的功能。

最好的MPEG—DVD转换软件

不管是自己拍摄或者从网上获得,你总是会想把MPEG视屏烧录到DVD里保存,DVDBuilder就是你当之无愧的选择,它快速,最重要的是,它是免费的。

最好的视频播放器/解码器

K-Lite Mega Codec Pack 几乎可以播放在地球上你能找到的所有格式的视频,而GSpot则是一款按需安装的播放器—你需要什么样的解码器,就下载安装什么。

最好的视频及流媒体播放软件

VLC是一款便携式跨平台、多媒体以及流媒体播放器,支持MPEG-1、MPEG-2、MPEG-4、DivX、mp3、ogg等等,同时还支持DVD与VCD。

最好的音频播放器

Winamp 与 foobar2000是最好的两款音频播放软件。ml_ipod是一个 Winamp的插件用来使Winamp支持
iPod,Winamp DSP Enhancer能提高声音的音质而不仅仅只是放大他们的音量。 foobar
2000是一个运行于Win平台的先进的音频播放器,他能支持非常流行的音频格式,当然,你不必去在乎它所占的磁盘空间是那样的少。

Audacity 是一款自由的音频编辑/播放软件。Exact Audio Copy则是专业的音频抓取软件,他能将CD复制到你的磁盘里,当然,他并不适合初级用户使用。

最好的音频转换软件

dBpowerAMP Music Converter能在保留ID标签的同时对音频进行转换与切割,他常常被称为声音的瑞士军刀。

最好的XviD/DivX转换软件

AutoGK是一款非常棒的Xvid/DivX格式转换软件,它能转换成多种其它音频格式,同时,他还拥有很多实用的功能。

最好的DVD封面搜搜软件

是不是常常把电影备份到DVD里却愁没有DVD封面啊?不用着急,使用iCover可以从其本身的6个数据库以及互联网搜索13,000张电影的封面,而且你可免费下载他们。

(Google translate: http://www.google.com/translate_t)

最好的IPod软件

忘记iTunes吧,YamiPod让你完全控制你的iPod,并且提供了更多的功能。

最好的硬盘分析软件

JDickReport 是一款非长棒的软件,它通过多种图表和文字信息让你完全掌握你的电脑里都存储着什么。

最好的软件集

TheOpenCD包含了非常多的任何人可以自由使用的免费软件以及开源软件,

最好的HTML编辑软件

NVU—比Dreamweaver或者Frontpage都要小但非常好的HTML编辑软件。BlueFish Editer也是一款非常稳定的HTML编辑软件,它主要功能集中在动态网页以及交互式网站的制作。

最好的CSS菜单设计软件

CSS Menu Designer可以依照你的需要自动创建漂亮的CSS菜单。

最好的压缩软件

现在已经有非常多的压缩软件,最主要的还是7-Zip和IZArc。7-Zip支持7z、ZIP、CAB、RAR、ARJ、GZIP、BZIP2、
Z、TAR、CPIO、RPM以及DEB;IZArc支持7-ZIP、A、ACE、ARC、ARJ、B64、BH、BIN、BZ2、BZA、C2D、
CAB、CDI、CPIO、DEB、ENC、GCA、GZ、GZA、HA、IMG、ISO、JAR、LHA、LIB、LZH、MDF、MBF、MIM、
NRG、PAK、PDI、PK3、RAR、RPM、TAR、TAZ、TBZ、TGZ、TZ、UUE、WAR、XXE、YZ1、Z、ZIP、ZOO等等。这
两个软件都还提供了很多其他功能。

最好的办公套件

毋庸置疑,最好的办公套件当属OpenOffice.Org,它具有非常多的MS Office的功能,还有很多自己特有的功能。

最好的多语言代码编辑软件

在这么多的计算机软件里,最好的代码编写软件还应为PHP Designer 2005 和
Notepad++,它们都支持语法高亮和语法折叠。PHP Designer
支持PHP、HTML、XML、CSS、JavaScript、Java、Perl、JavaScript、VB、C#、Java以及SQL;
Notepad++支持C、C++、Java、C#、XML、HTML、PHP、Javascript、RC resource
file、makefile、ASCII art file (extension .nfo)、doxygen、ini file、batch
file、ASP、VB/VBS source
files、SQL、Objective-C、CSS、Pascal、Perl、Python、Lua、TCL、Assembler、Ruby、
Lisp、Scheme、Properties、Diff、Smalltalk、Postscript and
VHDL。这写其实还仅仅只是这两个软件功能的冰山一角,它们还有更多的特色功能。

最好的AutoIt编辑软件

SciTe支持语法高亮和语法折叠,智能化与自动填写。

最好的PDF阅读软件

Foxit Reader非常的小(1.5Mb),所一你可以很快的下载它,它不需要安装,所以下载后你可以立即使用它。

最好的Linux操作系统

Ubuntu和Kubuntu是两个非常知名的Linux系统,他们都包含了很多的软件,另一个非常好的Linux是Damn Small Linux,它只有50Mb的大小,你完全可以在U盘上运行它。

最好的指南/手册制作软件

Wink是一个指南/手册制作软件,其主要功能是制作如何使用软件的帮组手册(如MS-word/excel使用帮助等)等。使用Wink,你能捕捉屏幕、鼠标动作、解释、按钮、标题等,为你的软件的用户制作出一个高效的使用手册。

最好的Windows CD制作软件

AutoStreamer是一款非常棒的Windows CD制作软件,通过它,我们只需要一张Windows安装CD以及一些你要集成的软件安装包就可以非常轻松地将最新升级文件和漏洞修补文件集成到Windows安装文件Windows Service Pack中。

Powered by ScribeFire.

八月 18, 2007

int epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;

Epoch time (Unix Time Stamp)

The
Unix epoch (also known as Unix Time Stamp) is the representation of
time as the number of non-leap seconds since 00:00:00 UTC on January 1,
1970, introduced by the Unix operating system, standardised in POSIX,
and later adopted by the Java programming language and JavaScript.
Because many computers today store the number of seconds as a 32-bit
signed integer, the Unix epoch is often said to last 231 seconds, thus
“ending” at 03:14:07 Tuesday, January 19, 2038 (UTC).

In POSIX conforming systems, the type time_t is often used to
represent times. It is an arithmetic type in the C programming
language. There is no requirement that time_t be a 32-bit quantity (it
could be a 64-bit integer or a floating point in double format), but
most systems define time_t as a signed 32-bit integer, and many
application programs may assume it, or may store values in a 32-bit
type. A signed 32-bit integer type can represent numbers ranging from
-2^31 to 2^31 - 1, that is, -2,147,483,648 to 2,147,483,647. In this
format, time_t will run out of positive integers 231-1 seconds (that is
24855 days, 3 hours, 14 minutes and 7 seconds) after the Epoch, in the
year 2038, and thus cannot represent times beyond that point. Programs
which must handle times beyond the rollover date will need to be
changed to accommodate a shift from 32-bit to 64-bit representation,
not unlike the Year 2000 problem. Adapting existing programs may be as
easy as re-compiling them with header files that declare time_t as a
64-bit integer, but other programs make deep assumptions as to the
nature of time_t. In fact, some claim that the expiration of the Unix
epoch timeframe may cause more damage than was predicted for the Y2K
bug. Compiling time_t as a 64-bit signed integer will allow
representation of all points in time 292 billion years before and after
1/1/1970.

To get the current Unix Time Stamp from your unix workstation use “date +%s” from a teminal.

The Perl case

The time() function is used in the Perl programming language to
retrieve the Unix epoch. Also, the variable $^T will be set to the
epoch value at the time the program began execution.

For measuring time in better granularity than one second, you may
use either the Time::HiRes module (from CPAN, and starting from Perl
5.8 part of the standard distribution), or if you have gettimeofday(2),
you may be able to use the syscall interface of Perl.

Sometimes you may want to convert the epoch time to real life time
measures or the opposite from real life time measures to epoch time,
for this you can use the localtime and timelocal subroutines from the
standard Time::Local module. It will look like this:

use Time::Local;
$TIME = timelocal($sec, $min, $hours, $mday, $mon, $year);

Sometimes a non-existing time, such as the time of creation of
something that does not exist, is indicated as 23:59, 31 Dec 1969.

Powered by ScribeFire.

八月 17, 2007


Introduction

In the few years that I have been a software developer I have work with
plenty of different programming languages. And the first thing that
causes you headaches in all of those languages are dates and how to
work with them. In this little tutorial I would like to show you how to
work with dates in C# .Net 2.

String to DateTime

 // String to DateTime String MyString; MyString = “1999-09-01 21:34 PM”;

 DateTime MyDateTime; MyDateTime = new DateTime(); MyDateTime = DateTime.ParseExact(MyString, “yyyy-MM-dd HH:mm tt”,                                  null);

DateTime to String

 //DateTime to String MyDateTime = new DateTime(1999, 09, 01, 21, 34, 00); String MyString; MyString = MyDateTime.ToString(”yyyy-MM-dd HH:mm tt”);

Format String For Dates

Your format string is your most
important key. In most of my projects I make it a constant and then
refer to the constant value in my code.

The following is the most communally used format characters:

Collapse
d - Numeric day of the month without a leading zero.dd - Numeric day of the month with a leading zero.ddd - Abbreviated name of the day of the week.dddd - Full name of the day of the week.

f,ff,fff,ffff,fffff,ffffff,fffffff - Fraction of a second. The more F’s the higher the presision.

h - 12 Hour clock, no leading zero.hh - 12 Hour clock with leading zero.H - 24 Hour clock, no leading zero.HH - 24 Hour clock with leading zero.

m - Minutes with no leading zero.mm - Minutes with leading zero.

M - Numeric month with no leading zero.MM - Numeric month with a leading zero.MMM - Abbreviated name of month.MMMM - Full month name.

s - Seconds with no leading zero.ss - Seconds with leading zero.

t - AM/PM but only the first letter.tt - AM/PM

y - Year with out century and leading zero.yy - Year with out century, with leading zero.yyyy - Year with century.

zz - Time zone off set with +/-.

Powered by ScribeFire.

八月 16, 2007

In this tutorial we will see how a .NET application can connect to a
MySQL server and perform queries on the database. The application uses
the MyODBC driver to establish an ODBC connection to the server.



Content:

Some developers are having a hard time connecting a .NET application to
a MySQL server. I found this task to be rather easy, using an ODBC
driver called MyODBC. There are several ways to connect to a MySQL
database from a .NET application, however using MyODBC proved to be the
simplest, cleanest and it works like a charm.

Setting up the MyODBC driver

Before starting you need to download and install MyODBC on the machine
that will act as the client (the machine that will connect to the
server). Here is what happens if you run the application and try to
connect without having MyODBC installed and configured:

Download MyODBC 3.51 or download from MySQL.com

After installing, open Data Sources (ODBC) from the Control Panel. Click Add… and the following window shows up:

Fill the TextBoxes with information about your MySQL server. The important fields are Server, User and Password. Click Test and with a little bit of luck, you will see the following message:

You can leave the database field as it is, or you can choose a default
database which the driver will connect to. Also, you don’t need to deal
with the other tabs of the window.

After clicking Ok to save the information, you will now see our newly created Data Source in the list:

Now we’re ready to build the application and run it.

Creating a .NET application that connects to a MySQL database

Download the project

Note that the code is written using .NET 2.0 and the project is created
in Visual Studio 2005. However, this won’t stop you from using the code
inside Visual Studio 2003 with .NET 1.1, because the code doesn’t need
any changes between versions of the .NET Framework.

Let’s look at the most important pieces in our code.

private System.Data.Odbc.OdbcConnection OdbcCon;

private System.Data.Odbc.OdbcCommand OdbcCom;

private System.Data.Odbc.OdbcDataReader OdbcDR;

private string ConStr;

Here we declared an ODBC connection, command and data reader. We will
need all these to connect, query and read data from the MySQL Server.
The ConStr
variable is a normal string variable that holds the connection string,
of course, we could have passed the connection string directly without
using an additional variable, but the code is more organized this way.

Now let’s have a look in the click event of the Connect button:

private void btnConnect_Click(object sender, EventArgs e)

{

   // Build the connection string

   ConStr = “DRIVER={MySQL ODBC 3.51 Driver};SERVER=” + txtIP.Text + “;PORT=” + txtPort.Text + “;DATABASE=” + txtDatabase.Text + “;UID=” + txtUsername.Text + “;PWD=” + txtPassword.Text + “;OPTION=3″;

   OdbcCon = new System.Data.Odbc.OdbcConnection(ConStr);

   // Enable the List Tables button

   btnListTables.Enabled = true;

   try

   {

      // Try openning the connection

      txtLog.AppendText(“Openning connection…\r\n”);

      // Make sure the connection is closed

      if (OdbcCon.State == ConnectionState.Closed)

      {

         OdbcCon.Open();

         txtLog.AppendText(“Connection opened\r\n”);

      }

   }

   catch (System.Data.Odbc.OdbcException Ex)

   {

      // An error occured, give details

      txtLog.AppendText(Ex.Message + “\r\n”);

      MessageBox.Show(“Could
not access the database.\r\nPlease make sure you completed the fields
with the correct information and try    again.\r\n\r\nMore
   details:\r\n”
+ Ex.Message, “Database connection error”, MessageBoxButtons.OK, MessageBoxIcon.Error);

   }

}

The connection string is initialized here, using data from the
TextBoxes on the form. Note the version of the MySQL ODBC driver,
inside. Carefully enclosing in try/catch blocks, the lines that open
the connection, we change the connection state of the ODBC connection
to Open. We first check to make sure the connection is not already
open.

Now to list the tables inside the database:

private void btnListTables_Click(object sender, EventArgs e)

{

   if (OdbcCon.State == ConnectionState.Open)

   {

      // Execute the SHOW TABLES query on the MySQL database

      OdbcCom = new System.Data.Odbc.OdbcCommand(“SHOW TABLES”, OdbcCon);

      OdbcDR = OdbcCom.ExecuteReader();

      txtLog.AppendText(“Tables inside “ + txtDatabase.Text + “:\r\n”);

      // Loop through the list of tables and display each one

      while (OdbcDR.Read())

      {

         txtLog.AppendText(“>> “ + OdbcDR[0] + “\r\n”);

      }

   }

}

We first check the state of the connection. If it is closed, we don’t
want to try to execute a command on the MySQL Server. Then we execute
the SHOW TABLES
query, which is the MySQL query for getting a list of tables in the
selected database. Using a DataReader we pass through each table and
display it inside the txtLog TextBox.

To keep this tutorial simple, I haven’t added any other commands to be
executed on the MySQL server, however you can perform any operation on
the server. You can create new databases, select values, create tables,
add values, edit values, delete databases and any other operation that
you can think of, that MySQL supports through a query.

Also I should mention that even though this is a Windows application,
the ODBC connection method works great with web applications too. That
means you can easily build ASP.NET applications that use a MySQL
database.

Here is the application running on Windows Vista:

Powered by ScribeFire.

八月 15, 2007

Before using the code, it is assumed that the MySQL database is existing in the system and is up and running. Then create a System DSN and give it the name which you give in the code. Also, make sure that you use the same UID and password. The below code connects to the MySQL database using the third party (Open Source) bridge ByteFX. This works the same way as the SqlConnection. For more information on the operations, please refer to the operation manual.

 ByteFX.Data.MySqlClient; 

………

//Now try to connect using ByteFX.//This can be downloaded from http://www.bytefx.com/download.ashx?id=8string myConnectionString =“DSN=MySQL;UID=root;PWD=root”; MySqlConnection myConnection = new MySqlConnection(myConnectionString);string myInsertQuery = “Select * from Authors”;MySqlCommand myCommand = new MySqlCommand(myInsertQuery);myCommand.Connection = myConnection;myConnection.Open();MySqlDataReader objReader = myCommand.ExecuteReader(); int nResultCount = 0;while (objReader.Read()){    ++nResultCount;}

Powered by ScribeFire.

1.WAP GPRS WLAN CSD
WAP(Wireless Application Protocol):无线网络应用协议
GPRS(Gerneral Packer Radio Service):通用无限分组业务
WLAN(Wireless Local Area Network):无线局域网
CSD(Circuit Switched Data ):电路交换数据业务
你可以这样简单理解:CSD GPRS WLAN是承载/接入方式,WAP是应用协议就像HTTP协议一样,CMNET CMWAP同属于GPRS接入方式,面向不同的接入点。

1.1WAP和GPRS有什么区别
wap是一种无线网络应用协议,而gprs是实现wap应用的一种网络传输技术方式。形象的说,wap如果是一封信,gprs就是送信到达的邮车。

wap现在有两种承载方式
    一是csd(电路交换数据传送方式)
    二是gprs方式(通用无线分组业务)

cds和gprs使用资费有差别
    csd(电路交换数据传送方式)按分钟收费的,一般0.15元/分钟。
    gprs方式(通用无线分组业务)这个是按网络信息交换流量来收费的。但他们在网络终端可以实现的功能是一样的。0.03元/KB
    csd必须基于GSM电路交换,通过拨号17266接入WAP服务,传输速率9.6Kbps,
    gprs理论上的最高传输速率为171.2Kbps,目前的实际传输速率一般为40Kbps左右,
    gprs更为优越的是按流量计费,比csd按时间计费要合理,同时gprs不会影响打进和呼出电话,而csd因为要占用电话电路,使用时无法接受来电。

2.wap接入点cmwap和cmnet有什么不同?
    CMWAP 和CMNET是移动人为划分的两个wap接入方式。前者是为手机WAP上网而设立的,后者则主要是为PC、笔记本电脑、PDA等利用GPRS上网服务。它们在实现方式上并没有任何差别,但因为定位不同,所以和CMNET相比,CMWAP便有了部分限制,资费上也存在差别。

连网方式不同
     就是说通过cmwap的方式访问,需要走移动的网关通过http协议去连接,这样的后果就是速度会变慢,相信很多朋友都用过代理服务器吧,就是那个感觉,但用手机的浏览器访问wap网站或使用网络功能,不会感觉到接入点的速度差别.因为手机本身处理速度有限制。而通过cmnet来连接的,就是直接连接到 internet上的服务器,速度会比cmwap的快一些。如果用手机做猫,连接电脑上网时才会体现出来。cmwap速度会很慢,而有很多限制,甚至有的地区根本无法用cmwap连接电脑,cmnet是移动专门的提供无线网络服务的接入点,速度基本和电话拨号上网相当。

资费不同
    各地cmwap一般是10-20元包月,而cmnet一般是100-200元包月。如果仅仅是在手机上使用网络服务的话,选择cmwap包月无疑是最实惠的。

3.怎么才能确认手机上网或其他业务使用产生的数据流量是 cmwap 还是cmnet?
    一般可以从“手机wap设置”上确认。但还是建议以查询本机的gprs使用详单为准。
    如果是手机+电脑,通过手机做猫让电脑上网,如果不更改接入点,都是默认产生cmnet流量,使用此业务手机内wap设置不会起作用。
    同时部分手机内置邮件收发程序也是需要默认的cmnet连接,否则无法收发邮件。
    有些需要连接网络的java程序在使用时会需要cmnet连接,有的可以设定更改,也有的是无法更改的。

Powered by ScribeFire.

八月 10, 2007

1. 在vs2005【解决方案管理器】中双击【properties】;
2. 选择【设置】tab page, 单击【查看代码】;
3. 在 Settings 类 的构造函数中增加如下代码:     this.SettingsLoaded += new
System.Configuration.SettingsLoadedEventHandler(Settings_SettingsLoaded);  4.
然后在添加如下事件:     private void Settings_SettingsLoaded(object sender,
System.Configuration.SettingsLoadedEventArgs e)
    {
        string connectionString = Settings.Default.anjouConnectionString;
        //修改连接字符串中的【数据库文件路径】
        connectionString = connectionString.Replace(@”\App_Data\db1.mdb”,
                                     System.Web.HttpContext.Current.Request.PhysicalApplicationPath+ @”\App_Data\db1.mdb”);
        //修改连接字符串中的【密码】
        connectionString = connectionString.Replace(”Database Password=123″, “Database Password=newpassword”);
        this[”anjouConnectionString”] = connectionString;

Powered by ScribeFire.

下一页 »