打印本文 打印本文  关闭窗口 关闭窗口
<展现C#> 第八章 用C#写组件
作者:采集员 文章来源:来源于网络 点击数: 更新时间:2005/9/10 12:27:15
说明连接成功。
    对于 Whois 查找,我必须首先发出一些信息给服务器??我要查找的域名。要完成此项工作,首先获得一个引用给当
前TCP连接的双向流(第25行)。接着附加上一个回车/换行对 给域名,以表示询问结束。重新以字节数组打包,向Whois
服务器发送一个请求(第30行)。
    余下的代码和RequestWebPage类极其相似。在该类中,我再次利用一个缓冲区从远程服务器读入回应。当缓冲区完成
读入后,连接被断开。返回的回应被转给了调用者。我明确地调用 Close 方法的原因是我不想等待垃圾收集器毁坏连接。
连接时间不要过长,以免占用TCP端口这种稀有资源。
    在可以使用.NET 组件中的类之前,你必须把它作为一个库来编译。尽管现在有了一个已定义的名字空间,该编译命令
仍然没有变:
    csc /r:System.Net.dll /t:library /out:whois.dll whois.cs
    注意,如果你想该库按与C#源文件相同的方法命名,就没有必要规定 /out:开关。规定该开关是一个良好的习惯,因
为很多项目不会只由单个源文件组成。如果你规定了多个源文件,该库以名单中的第一个命名。

8.2.2  在客户应用程序中使用名字空间
    由于你使用了名字空间开发组件,所以客户也要引入名字空间
    using Presenting.CSharp;
    或者给名字空间中的成员使用完全资格名(fully  qualified name),例如
    Presenting.CSharp.WhoisLookup.Query(...);

    如果你不期望在名字空间中引入的成员之间出现冲突,using  标志( directive)是首选,特别是由于你具有很少的
类型时。使用组件的客户程序样本在清单8.4中给出。

    清单  8.4  测试 WhoisLookup     组件

1: using System;
2: using Presenting.CSharp;
3:
4: class TestWhois
5: {
6:  public static void Main()
7:  {
8:   string strResult;
9:   bool bReturnValue;
10:
11:   try
12:   {
13:    bReturnValue = WhoisLookup.Query("microsoft.com", out strResult);
14:   }
15:   catch (Exception e)
16:   {
17:    Console.WriteLine(e);
18:    return;
19:   }
20:   if (bReturnValue)
21:    Console.WriteLine(strResult);
22:   else
23:    Console.WriteLine("Could not obtain information from server.");
24:  }
25: }

    第2行利用using 标志引入了Presenting.CSharp名字空间。现在,我无论什么时候引用WhoisLookup ,都可以忽略名
字空间的完全资格名了。
    该程序对 microsoft.com 域进行一次Whois 查找??你也可以用自己的域名代替microsoft.com 。允许命令行参数传
递域名,可使客户的用途更广。清单8.5 实现了该功能,但它不能实现适当的异常处理(为了使程序更短)。

    清单  8.5  传递命令行参数给Query 方法

1: using System;
2: using Presenting.CSharp;
3:
4: class WhoisShort
5: {
6:  public static void Main(string[] args)
7:  {
8:   string strResult;
9:   bool bReturnValue;
10:
11:   bReturnValue = WhoisLookup.Query(args[0], out strResult);
12:
13:   if (bReturnValue)
14:    Console.WriteLine(strResult);
15:   else
16:    Console.WriteLine("Lookup failed.");
17:  }
18: }

    你所必须做的就是编译这个应用程序:
    csc /r:whois.dll whoisclnt.cs
    接着可以使用命令行参数执行该应用程序。例如,以 microsoft.com参数执行
    whoisclnt microsoft.com
    当查询运行成功时,就会出现 microsoft.com的注册信息。(清单8.6 显示了输出的简略版本)  这是一个很方便的
小程序,通过组件化的途径写成的,花不到一个小时。如果用C++编写,要花多长时间?很幸运,我再也想不起当第一次用
C++这样做时,花了多长的时间。

    清单 8.6   有关 microsoft.com (简略) 的Whois 信息
D:CSharpSamplesNamespace>whoisclient
...

Registrant:
Microsoft Corporation (MICROSOFT-DOM)
  1 microsoft way
  redmond, WA 98052
  US
  Domain Name: MICROSOFT.COM

  Administrative Contact:
   Microsoft Hostmaster (MH37-ORG) msnhst@MICROSOFT.COM
  Technical Contact, Zone Contact:
   MSN NOC (MN5-ORG) msnnoc@MICROSOFT.COM
  Billing Contact:
   Microsoft-Internic Billing Issues (MDB-ORG)     msnbill@MICROSOFT.COM

  Record last updated on 20-May-2000.
  Record expires on 03-May-2010.
  Record created on 02-May-1991.
  Database last updated on 9-Jun-2000 13:50:52 EDT.

  Domain servers in listed order:

  ATBD.MICROSOFT.COM      131.107.1.7
  DNS1.MICROSOFT.COM      131.107.1.240
  DNS4.CP.MSFT.NET       207.46.138.11
  DNS5.CP.MSFT.NET       207.46.138.12

8.2.3  增加多个类到名字空间
    使WhoisLookup和RequestWebPage 类共存于同一个名字空间是多么的美妙。既然WhoisLookup已是名字空间的一部分,
所以你只须使RequestWebPage 类也成为该名字空间的一部分。
    必要的改变很容易被应用。你只需使用名字空间封装RequestWebPage 类就可以了:

namespace Presenting.CSharp
{
public class RequestWebPage
{
...
}
}

    尽管两个类包含于两个不同的文件,但在编译后,它们都是相同名字空间的一部分:
    csc /r:System.Net.dll /t:library /out:presenting.csharp.dll whois.cs webrequest.cs

    你不必要按照名字空间的名字给DLL命名。然而,这样做会有助你更容易你记住,当编译一个客户应用程序时要引用哪
一个库。
  
8.3  小结
    在这一章中,你学到了如何构建一个可以在客户程序中使用的组件。最初,你不必关心名字空间,但后面第二个组件
中介绍了该特性。名字空间在内外部均是组织应用程序的好办法。
    C#中的组件很容易被构建,而且只要库和应用程序共存于相同的目录,你甚至不必进行特殊的安装。当要创建必须被
多个客户使用的类库时,步骤就有所改变??而下一章将会告诉你为什么。

上一页  [1] [2] 



打印本文 打印本文  关闭窗口 关闭窗口