清单 8.3 在名字空间中实现 WhoisLookup类
1: using System;
2: using System.Net.Sockets;
3: using System.IO;
4: using System.Text;
5:
6: namespace Presenting.CSharp
7: {
8: public class WhoisLookup
9: {
10: public static bool Query(string strDomain, out string strWhoisInfo)
11: {
12: const int BUFFER_SIZE = 128;
13:
14: if ("" == strDomain)
15: throw new ArgumentException("You must specify a domain name.");
16:
17: TCPClient tcpc = new TCPClient();
18: strWhoisInfo = "N/A";
19:
20: // 企图连接 whois 服务器
21: if (tcpc.Connect("whois.networksolutions.com", 43) != 0)
22: return false;
23:
24: // 获取流
25: Stream s = tcpc.GetStream();
26:
27: // 发送请求
28: strDomain += "\r\n";
29: Byte[] bDomArr = Encoding.ASCII.GetBytes(strDomain.ToCharArray());
30: s.Write(bDomArr, 0, strDomain.Length);
31:
32: Byte[] Buffer = new Byte[BUFFER_SIZE];
33: StringBuilder strWhoisResponse = new StringBuilder("");
34:
35: int BytesRead = s.Read(Buffer, 0, BUFFER_SIZE);
36: while (BytesRead != 0 )
37: {
38: strWhoisResponse.Append(Encoding.ASCII.GetString(Buffer,0,BytesRead));
39: BytesRead = s.Read(Buffer, 0, BUFFER_SIZE);
40: }
41:
42: tcpc.Close();
43: strWhoisInfo = strWhoisResponse.ToString();
44: return true;
45: }
46: }
47: }
名字空间在第6行被声明,而且它用第7行和第47行的大括弧括住了WhoisLookup类。要声明自己新的名字空间,实际要做的就是这些。
在WhoisLookup类中当然具有一些有趣代码,特别是由于它说明了使用C#进行socket编程是多么的容易。在static Query method中经过 not-so-stellar域名检查之后,我实例化了TCPClient类型的一个对象,它用来完成具有 Whois服务器的43端口上的所有通讯。在第21行建立了服务器连接:
if (tcpc.Connect("whois.networksolutions.com", 43) != 0)
因为连接失败是预料到的结果,所以这个方法不能引发一个异常。(你还记住异常处理的"要"和"不要"吗?) 返回值是一个错误代码,而返回零则说明连接成功。
对于 Whois 查找,我必须首先发出一些信息给服务器——我要查找的域名。要完成此项工作,首先获得一个引用给当前TCP连接的双向流(第25行)。接着附加上一个回车/换行对 给域名,以表示询问结束。重新以字节数组打包,向Whois 服务器发送一个请求(第30行)。
余下的代码和RequestWebPage类极其相似。在该类中,我再次利用一个缓冲区从远程服务器读入回应。当缓冲区完成读入后,连接被断开。返回的回应被转给了调用者。我明确地调用 Close 方法的原因是我不想等待垃圾收集器毁坏连接。连接时间不要过长,以免占用TCP端口这种稀有资源。在可以使用。NET 组件中的类之前,你必须把它作为一个库来编译。尽管现在有了一个已定义的名字空间,该编译命令仍然没有变:
csc /r:System.Net.dll /t:library /out:whois.dll whois.cs
注意,如果你想该库按与C#源文件相同的方法命名,就没有必要规定 /out:开关。规定该开关是一个良好的习惯,因为很多项目不会只由单个源文件组成。如果你规定了多个源文件,该库以名单中的第一个命名。

