C#高级编程:信道-from(http://www.tzwhx.com/newOperate/html/1/12/124/10365.html)

信道用于.NET客户机和服务器之间的通信。.NET Framewprk 1.1已有的信道类使用TCPHTTP进行通信。我们可以为其他的协议创建定制的信道。

大多数Web服务使用的是HTTP信道。它使用HTTP协议进行通信。因为防火墙通常让端口80处于打开的状态,目的是让客户机能够访问Web服务器,所以.NET Remoting Web服务可以监听端口80,让客户机更容易使用它们。

Internet上也可以使用TCP信道,但是必须配置防火墙,以使客户机能够访问TCP信道所使用的指定端口。与HTTP信道相比,在内部网中使用TCP信道能够进行更加有效的通信。

当执行远程对象上的方法调用时,客户信道对象就把消息发送到远程信道对象中。

服务器应用程序和客户应用程序都必须创建信道。下面的代码说明了如何在服务器端创建TcpServerChannel

using System.Runtime.Remoting.Channels.Tcp;

  ...

TcpServerChannel channel = new TcpServerChannel(8086);

构造函数的参数指定TCP网络接口监听哪个端口。服务器信道必须指定一个所有人都知道的端口,在访问服务器时,客户必须使用该端口。但是,在客户机上创建TcpClientChannel时,不必指定一个人人都知道的端口,TcpClientChannel的默认构造函数会选择一个可以使用的端口,在客户机与服务器连接时,该端口被传递给服务器,以便服务器能够把数据发回给客户。

创建新的信道实例,会使网络接口立即转换到监听状态,在命令行中键入netstat –a,可以验证插口是否处于监听状态。

HTTP信道的使用方式类似于TCP信道。可以指定服务器能在哪个端口上创建监听网络接口。

服务器可以监听多个信道。下面的代码在HelloServer.cs文件中创建了一个HTTP信道和一个TCP信道:

using System;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

using System.Runtime.Remoting.Channels.Http;

namespace Wrox.ProCSharp.Remoting

{

public class HelloServer

{

  public static void Main(string[] args)

  {

TcpServerChannel tcpChannel = new TcpServerChannel(8086);

HttpServerChannel httpChannel = new HttpServerChannel(8085);

// register the channel

ChannelServices.RegisterChannel(tcpChannel);

ChannelServices.RegisterChannel(httpChannel);

//...

  }

信道类必须实现IChannel接口。IChannel接口有以下两个属性:

●ChannelName:这个属性是只读的,它返回信道的名称。信道的名称取决于协议的类型,例如,HTTP信道的名称为HTTP

●ChannelPriority:这个属性也是只读的。在客户机和服务器之间可以使用多个信道进行信,优先权定义了信道的次序。在客户机上,具有较高优先权的信道先与服务器进行连接。优先值越大,优先权就越大,其默认值是1,但允许使用负值创建较低的优 先权。

实现的其他接口要根据信道的类型而决定,服务器信道实现的接口是IChannelReceiver,而客户信道实现的接口是IChannelSender

HTTPChannel类和TcpChannel类都可以用在服务器和客户机。它们实现IChannelSender接口和 IChannelReceiver接口。这些接口都是由IChannel接口派生而来的。

客户端的IChannelSender除了有IChannel之外,还有一个方法CreateMessageSink(),这个方法返回一个实现IMessageSink接口的对象。IMessageSink接口除了可以把异步消息放到信道中之外,还可以把同步消息放到信道中。在使用服务器端的接口IChannelReceiver时,通过StartListening()可以把信道设置为监听状态,而通过StopListening()则可以停止对信道的监听。此外,还有一个用于访问所获取的数据的属性ChannelData

使用信道类的属性,可以获取信道配置的信息。HTTP信道和TCP信道都有ChannelName属性、ChannelPriority属性和ChannelData属性。使用ChannelData属性可以获取保存在ChannelDataStore类中的URI信息。此外,HttpChannel还有一个Scheme属性。下面的帮助方法ShowChannelProperties()在文件HelloServer.cs中,显示了信道的配置信息:

protected static void ShowChannelProperties(IChannelReceiver channel)

{

Console.WriteLine("Name: " + channel.ChannelName);

Console.WriteLine("Priority: " + channel.ChannelPriority);

if (channel is HttpChannel)

{

  HttpChannel httpChannel = channel as HttpChannel;

  Console.WriteLine("Scheme: " + httpChannel.ChannelScheme);

}

ChannelDataStore data = (ChannelDataStore)channel.ChannelData;

foreach (string uri in data.ChannelUris)

{

  Console.WriteLine("URI: " + uri);

}

Console.WriteLine();

}

Main()方法中,创建信道之后,就调用ShowChannelProperties()方法。启动服务器就可以得到图16-5所示的控制台输出信息。从中可以看出,TcpServerChannel的默认名称是tcp,而HTTP信道的默认名称是http。这两个信道的默认优先权都是1,用构造函数设置的端口显示在URI中。信道的URI显示协议、IP地址和端口号。

TcpServerChannel tcpChannel = new TcpServerChannel(8086);

ShowChannelProperties(tcpChannel);

HttpServerChannel httpChannel = new HttpServerChannel(8085);

ShowChannelProperties(httpChannel);

  16-5

1. 设置信道属性

使用构造函数TCPServerChannel(IDictionaryIServerChannelSinkProvider),可以在一个列表中设置信道的所有属性。Hashtable 类实现 IDictionary,因此,使用这个类可以设置Name属性、Priority属性和 Port属性。为了使用Hashtable类,必须声明使用System.Collections命名空间。

在类TcpServerChannel的构造函数中,除了参数IDictionary之外,还可以传递实现接口IServerChannelSinkProvider的对象。本例中设置的是SoapServerFormatterSinkProvider而不是BinaryServerFormatterSinkProvider,前者是TcpServerChannel的默认值。SoapServerFormatter SinkProvider类的默认实现把SoapServerFormatterSink类与使用SoapFormatter的信道联系起来,以转换数据,使之能进行传输:

IDictionary properties = new Hashtable();

properties["name"] = "TCP Channel with a SOAP Formatter";

properties["priority"] = "20";

properties["port"] = "8086";

SoapServerFormatterSinkProvider sinkProvider =

  new SoapServerFormatterSinkProvider();

TcpServerChannel tcpChannel =

  new TcpServerChannel(properties, sinkProvider);

ShowChannelProperties(tcpChannel);

服务器的新控制台输出结果显示了TCP信道的新属性,如图16-6所示。

根据信道的类型,可以指定不同的属性。TCPHTTP信道都支持本例中使用的namepriority信道属性。这些信道也支持其他属性,例如bindTo,如果计算机配置了多个IP地址,bindTo指定绑定可以使用的IP地址。TCP服务器信道支持rejectRemoteRequests,只允许从本地计算机上连接客户机。

  16-6

2. 信道的“可**性”

创建的定制信道可以使用HTTPTCP之外的其他协议发送消息。此外,也可以对现有的信道进行扩展:

发送部分必须实现IChannelSender接口。最重要的部分是CreateMessageSink()方法,在该方法中,客户要发送URL,此外,使用这个方法可以实例化与服务器的连接。在这里必须创建消息接收器,代理对象使用该消息接收器把消息发送到信道中。

接收部分必须实现IChannelReceiver接口。必须在ChannelData get属性中启动监听,然后,可以等待一个线程接收来自客户的数据。在对消息进行解组之后,使用ChannelServices.SyncDispatchMessage()把消息分派给对象。


你可能感兴趣的:(Opera)