本文的发布号曾为 CHS307546 本文讨论一种 Microsoft 产品的 Beta 版本。本文中的信息按“原样”提供,如有更改恕不另行通知。
对于该 Beta 产品,Microsoft 不提供正式的产品支持。有关获取对 Beta 版本的支持的信息,请参阅 Beta 产品文件中包括的文档资料,或查看您下载此版本的站点。
有关本文的 Microsoft Visual Basic .NET 版本,请参见 301116。
本任务的内容
- 摘要
-
- 要求
- 创建远程服务器对象
- 创建远程服务器应用程序
- 创建客户机应用程序
- 参考
概要
本文演示如何按值将对象封送到远程服务器。 在按值封送对象时,就会创建一个该对象的副本,并将其序列化传送到服务器。 任何对该对象的方法调用都是在服务器上进行的。 因为需要将对象序列化传送到服务器,所以,必须使用 [Serializable] 属性修饰要传递对象的类定义。
本文阐述了下列 Microsoft 知识库文章中描述的一些概念:
- 300951 HOW TO: Create a Remote Server Using Visual Basic .NET(HOW TO:使用 Visual Basic .NET 创建远程服务器)
- 300943 HOW TO: Create a Client to a Remote Server Using Visual Basic .NET(HOW TO:使用 Visual Basic .NET 创建到远程服务器的客户机)
备注: 完成本文中的步骤 不 需要阅读这些文章。
返回页首
要求
下表概括了推荐使用的硬件、软件、网络架构以及所需的 Service Pack:
- Microsoft Windows 2000 Professional、Windows 2000 Server、Windows 2000 Advanced Server 或 Windows NT 4.0 Server
- Microsoft Visual Studio .NET
本文假定您熟悉下列主题:
- Visual Studio .NET
- 网络基础知识
返回页首
创建远程服务器对象
创建服务器应用程序的第一步是创建服务器对象。服务器对象在服务器上,客户机应用程序要实例化它并与之通讯。客户机应用程序是通过客户机上创建的代理对象实现这一点的。您的名为 HelloServer 的服务器对象将放在一个类库 (DLL) 中。 在同一个项目中,还定义将从客户机传递到服务器的类。此类名为 ForwardMe。 因为您希望按值封送 ForwardMe 类,所以,需要使用 [Serializable] 属性修饰 ForwardMe 类。
- 打开 Visual Studio .NET。
- 新建一个 Visual C# .NET 类库应用程序。默认情况下创建 Class1.cs。
- 在解决方案资源管理器中,将 Class1.cs 文件重命名为 ServerClassValue.cs。
- 打开 ServerClassValue.cs。导入 System.Diagnostics 名称空间,这样,以后就不需要在代码中完全限定名称了。
using System; using System.Diagnostics;
-
添加两个类,即 HelloServer 和 ForwardMe。 HelloServer 是从 MarshalByRefObject 类继承的,而且 ForwardMe 类使用 <Serializable> 自定义属性。 在将对象按值传递到远程服务器时,此标记允许将 ForwardMe 类以流的形式输入和输出服务器。
HelloServer 是客户机应用程序使用的主类。ForwardMe 用来将对象数据从客户机发送到服务器。 因为 ForwardMe 不是从 MarshalByRefObject 继承的,所以将它按值传递到服务器。
public class HelloServer : MarshalByRefObject { } [Serializable] public class ForwardMe { }
- 将公用方法 HelloMethod 添加到 HelloServer,后者将 ForwardMe 对象作为参数。 使用此方法将 ForwardMe 对象传递到服务器。此方法调用这一对象的 CallMe 方法。您的 HelloServer 类现在应该如下所示:
public class HelloServer : MarshalByRefObject { public void HelloMethod(ForwardMe obj ) { obj.CallMe(); } }
- 将一个公用方法添加到 ForwardMe 类,并根据执行此代码的进程来命名此方法。 因为您将整个对象序列化传递到服务器(按值封送),所以此代码在服务器的进程中运行。
[Serializable] public class ForwardMe { public void CallMe() { Console.WriteLine("CallMe was executed in: " + Process.GetCurrentProcess().ProcessName.ToString()); } }
- 生成该项目以创建 ServerClassValue.dll 程序集。
- 保存并关闭该项目。
返回页首
创建远程服务器应用程序
在创建了客户机将与之通讯的服务器对象后,必须将此对象注册到远程处理框架中。注册不仅包括对对象进行注册,还包括启动服务器并让它侦听一个端口以便客户机进行连接。为此,您需要一个能创建可执行文件的项目类型。 将服务器对象包含在另一个项目中,以便能方便地从客户机引用服务器对象。如果您在此项目中包括了服务器对象,您不能引用它,因为只可以设置到 DLL 文件的引用。
- 打开 Visual Studio .NET。
- 新建一个 Visual C# .NET 控制台应用程序以启动远程服务器。默认情况下创建 Class1.cs。
- 在解决方案资源管理器中,将 Class1.cs 文件重命名为 ServerObjectValue.cs。
- 给项目添加一个到 System.Runtime.Remoting 名称空间的引用。
- 添加对 ServerClassValue.dll 程序集(在创建远程服务器对象一节中创建的)的引用。
- 对 Remoting、Remoting.Channels 和 Remoting.Channels.Tcp 名称空间使用 using 语句,这样,在后面的代码中就不需要限定这些名称空间中的声明了。using 语句必须位于所有其他声明之前。
using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp;
- 声明相应的变量以初始化一个 TcpChannel 对象,该对象监听某个端口以便客户机进行连接(本例中为 8085 端口)。使用 RegisterChannel 方法注册客户机将用来与通道服务进行通讯的通道。在 Module1 的 Main 过程中添加声明代码:
TcpChannel chan = new TcpChannel(8085); ChannelServices.RegisterChannel(chan);
- 调用 RemotingConfiguration 对象的 RegisterWellKnownType 方法,将 ServerClassValue 对象注册到远程处理框架中。在代码中必须指定下列参数:
- 正在注册的对象的完整类型名称(本例中是 ServerClassValue.HelloServer),后面跟着程序集名称 ServerClassValue。必须指定名称空间的名称和类名。因为在前面的部分中没有指定名称空间,所以使用默认的根名称空间。
- 对象将要发布到的终结点的名称。客户机需要知道此名称以便连接到该对象。 请使用 RemoteTestValue。
- 对象模式,可以是 SingleCall 或 Singleton。本例指定 SingleCall。对象模式指定了在服务器上激活该对象时的有效期。对于 SingleCall 对象,针对客户机的每次调用都会创建类的一个新实例,即使在同一客户机多次调用同一方法的情况下也是如此。或者,只创建一次 Singleton 对象,所有客户机都与同一个对象通讯。
RemotingConfiguration.RegisterWellKnownServiceType( Type.GetType("ServerClassValue.HelloServer, ServerClassValue"), "RemoteTestRef", WellKnownObjectMode.SingleCall);
- 使用 Console 对象的 ReadLine 方法保持服务器应用程序的运行:
Console.WriteLine("Press <ENTER> to exit..."); Console.ReadLine();
- 生成项目。
- 保存并关闭项目。
返回页首
创建客户机应用程序
- 打开 Visual Studio .NET。
- 在 Visual C# .NET 中新建控制台应用程序。默认情况下创建 Class1.cs。
- 在解决方案资源管理器中,将 Class1.cs 文件重命名为 ClientAppValue.cs。
- 给项目添加一个到 System.Runtime.Remoting 名称空间的引用。
- 添加对 ServerClassValue.dll 程序集(在创建远程服务器对象一节中创建的)的引用。
- 对 Remoting、Remoting.Channels 和 Remoting.Channels.Tcp 名称空间使用 using 语句,这样,在后面的代码中就不需要限定这些名称空间中的声明了。using 语句必须位于所有其他声明之前。
using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using ServerClassValue;
-
声明相应的变量以初始化一个 TcpChannel 对象,客户机将使用该对象连接到服务器应用程序。使用 RegisterChannel 方法将该通道注册到通道服务。
然后,必须初始化一个新的 ForwardMe 对象,该对象将被传递到远程服务器对象。 切记,将按值传递该对象。在 Module1 的 Main 过程中添加声明代码:
TcpChannel chan = new TcpChannel(); ChannelServices.RegisterChannel(chan); ForwardMe objForwardMe = new ForwardMe();
- 声明和实例化远程服务器。在本例中,使用 Activator 对象的 GetObject 方法实例化 HelloServer 对象。在代码中必须指定下列参数:
- 正在注册的对象的完整类型名称(本例中是 ServerClassValue.HelloServer),后面跟着程序集名称 ServerClassValue。必须指定名称空间的名称和类名。因为在前面的部分中没有指定名称空间,所以使用默认的根名称空间。
- 要激活的对象的统一资源标识符 (URI)。 URI 必须包含协议 (tcp)、计算机名 (localhost)、端口 (8085) 和服务器对象的终结点 (RemoteTestValue)。 若要访问位于本地服务器上的 ServerClassValue 远程服务器,URI 为 tcp://localhost:8085/RemoteTestValue。
HelloServer objHelloServer; objHelloServer = (HelloServer)Activator.GetObject( typeof(HelloServer), "tcp://localhost:8085/RemoteTestRef"); if (objHelloServer == null) Console.WriteLine("Could not locate server"); else { //See next step }
-
如果服务器对象实例化成功,则调用服务器对象的 HelloMethod ,并将新创建的 objForwardMe 对象传递给该方法。
切记,HelloMethod 调用 ForwardMe 对象的 CallMe 方法,该方法向控制台窗口显示运行该代码所在进程的名称。
HelloServer objHelloServer; objHelloServer = (HelloServer)Activator.GetObject( typeof(HelloServer), "tcp://localhost:8085/RemoteTestRef"); if (objHelloServer == null) Console.WriteLine("Could not locate server"); else { objHelloServer.HelloMethod(objForwardMe); Console.WriteLine("Method executed, check server window for output."); }
- 使用 Console 对象的 ReadLine 方法保持客户机应用程序的运行:
Console.WriteLine("Press <ENTER> to exit..."); Console.ReadLine();
- 生成项目。
- 确保服务器应用程序在运行中。
- 运行客户机项目以测试客户机和服务器之间的通讯。
运行客户机时,当该方法执行结束时,您就会收到通知。 注意, CallMe 方法的输出结果显示在服务器的控制台窗口中,而不是显示在客户机的控制台窗口中。这是因为对象是按值封送到服务器的。
返回页首
参考
有关 TcpChannel 类的更多信息,请访问以下 .NET 框架类程序库 Web 站点:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemRuntimeRemotingChannelsTcpTcpChannelClassTopic.asp
有关 RegisterWellKnownServiceType 方法的更多信息,请访问以下 .NET 框架类程序库 Web 站点:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemRuntimeRemotingRemotingConfigurationClassRegisterWellKnownServiceTypeTopic.asp
有关 Microsoft .NET 远程处理框架的介绍(一般性的 .NET 开发技术文章),请访问以下 MSDN 站点:
http://msdn.microsoft.com/library/techart/remoting.htm
返回页首
这篇文章中的信息适用于:
- Microsoft Visual C# .NET Beta 2
最近更新: | 2001-11-5 (1.0) |
关键字 | kbDSupport kbhowto kbHOWTOmaster kbnokeyword KB307546 kbAudDeveloper |