.NET Remoting

本文介绍了Remoting技术的基本概念,包括远程对象、远程服务器和客户端的组成,并通过一个HelloWorld示例详细展示了如何实现远程对象的创建、服务器端的配置及客户端的调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、Remoting简介 

  其主要的结构,分为:远程对象、提供远程对象的远程服务器,以及可以访问何使用远程对象的客户端。这三个部分,可以分布于同一台计算机的同一个进程,或者是不同的进程,也可以是处于网络上的不同的计算机。Remoting技术最大的特点,就是对远程通信的过程进行了抽象和封装,使开发人员不必去处理底层通信的细节,而可以把重点放在对业务逻辑的处理上。而且Remoting的通信协议也比较灵活,可以使用多个通信协议、不同的数据格式类型,以及不同类型的序列化机制。在某些情况下,Remoting还允许你使用自定义的数据格式。

2、用一个经典的Hello World来开始我们的Remoting之旅吧!我们的例子,也是分三步开始:

  1. 建立远程对象;
  2. 建立远程服务器;
  3. 建立客户端程序,调用远程对象;

准备好了吗?Let''s go~!

首先,我们编写远程对象的类

		
          namespace RemoteObject
          {
	      public __gc class RemoteObjClass:public MarshalByRefObject
	      {
		   public:
			String * DisplayMessage()
			{
			    return S"Hello World!";
			}
	      };
          }      

  这是一个很简单的类,DisplayMessage成员函数,返回一串字符:Hello World。在这里,我们要注意MarshalByRefObject,我们的类就是从它继承而来。在.NET中有应用程序域的概念,MarshalByRefObject类,能让对象跨应用域被访问。

然后,我们来建立远程服务器,代码如下:

           using namespace System;
	   using namespace System::Runtime::Remoting;
	   using namespace System::Runtime::Remoting::Channels;
	   using namespace System::Runtime::Remoting::Channels::Tcp;
           using namespace RemoteObject;

	  int _tmain()
	  {
    	     // TODO: 请用您自己的代码替换下面的示例代码。
	     TcpChannel *Channel=new TcpChannel(8888);
	     ChannelServices::RegisterChannel(Channel);
	     RemotingConfiguration::RegisterWellKnownServiceType(
		Type::GetType(
			"RemoteObject.RemoteObjClass,RemoteObject"),
			 S"Test",WellKnownObjectMode::SingleCall);

   	     Console::WriteLine(S"Server is running...");
	     Console::ReadLine();
	     return 0;
          }      

(注:服务端和客户端,由于用到Remoting相关的类,所以需要在工程中,添加对System.Runtime.Retmoting的引用)
服务器和客户端之间的通信,是借由通道来实现的。在我们的服务器的代码中,首先,就是建立一个端口好为8888的Tcp通道,数据使用二进制方式传输,这样,服务器端将在端口8888进行监听。然后ChannelServices::RegisterChannel注册Tcp通道和服务。RemotingConfiguration::RegisterWellKnownServiceType把需要被远程访问的对象注册为已知类型。第一个参数,为对象的类型,第二个参数,是一个字符串,它和远程客户端访问的时候,用的URI有关。举个例子,在我们的程序中,本机调试的情况下,客户端访问客户端的远程对象的时候URI的地址就为: tcp://localhost:8888/Test ,localhost是指向本机的,如果在内部网络中,可以指定为服务器端的IP地址。 第三个参数,是调用的方式,在Remoting中,分为Singleton和SingleCall。二者的差别,我在以后的文章中会介绍。SingleCall,会在客户端每次访问的时候,创建一个实例,而Singleton只是创建一个实例,以后客户端的调用,都是共享这个实例。

实现远程客户端:

       #include "stdafx.h"
       #using 

       using namespace System;
       using namespace System::Runtime::Remoting;
       using namespace System::Runtime::Remoting::Channels;
       using namespace System::Runtime::Remoting::Channels::Tcp;

       using namespace RemoteObject;

       int _tmain()
       {
           TcpClientChannel *Channel=new TcpClientChannel();
	   ChannelServices::RegisterChannel(Channel);

           RemoteObjClass *pObj=static_cast(
				Activator::GetObject(
					Type::GetType("RemoteObject.RemoteObjClass,RemoteObject"),
					S"tcp://localhost:8888/Test"));

	   Console::WriteLine(S"Return String is:{0}",pObj->DisplayMessage());
	   Console::ReadLine();
	   return 0;
       }      

  在我们建立了服务端和远程对象之后,客户端就比较简单了。主要就是创建一个TcpChannel对象,用于和服务器端通信,不同的地方,是我们不需要指定一个端口。因为在客户端可以使用任何一个随机的端口。Activator::GetObject用来获取对远程对象的引用。之后,我们就可以像调用本地对象一样,来调用远程对象的方法了。程序的运行结果如下图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值