您的位置:首页 > 编程语言 > C#

图解C#中实现远程调用(Remoting)的示例代码(一)

2010-07-09 13:14 996 查看
先看下面的代码:

新建C/S间交互的数据类型(即远程对象类):





全部代码如下:

#region Using directives

using System;

#endregion

namespace Wrox.ProCSharp.Remoting
{

[Serializable]
public class MySerialized
{
public MySerialized(int val)
{
a = val;
}
public void Foo()
{
Console.WriteLine("MySerialized.Foo called");
}
public int A
{
get
{
Console.WriteLine("MySerialized.A called");
return a;
}
set
{
a = value;
}
}
protected int a;
}
public class MyRemote : System.MarshalByRefObject
{
public MyRemote(int val)
{
a = val;
}
public void Foo()
{
Console.WriteLine("MyRemote.Foo called");
}
public int A
{
get
{
Console.WriteLine("MyRemote.A called");
return a;
}
set
{
a = value;
}
}
protected int a;
}

public class Hello : System.MarshalByRefObject
{
public Hello()
{
Console.WriteLine("Constructor called");
}
~Hello()
{
Console.WriteLine("Destructor called");
}

public string Greeting(string name)
{
Console.WriteLine("Greeting called");
return "Hello, " + name;
}

public MySerialized GetMySerialized()
{
return new MySerialized(4711);
}
public MyRemote GetMyRemote()
{
return new MyRemote(4712);
}

}
}


编译之。

新建服务端:



在引用中追加工程RemoteHello以及.net组件System.Runtime.Remoting。





代码如下:

#region Using directives

using System;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Channels.Ipc;

#endregion

namespace Wrox.ProCSharp.Remoting
{
class Program
{
static void ShowChannelProperties(IChannelReceiver channel)
{
Console.WriteLine("Name: " + channel.ChannelName);
Console.WriteLine("Priority: " + channel.ChannelPriority);
if (channel is HttpServerChannel)
{
HttpServerChannel httpChannel = channel as HttpServerChannel;
Console.WriteLine("Scheme: " + httpChannel.ChannelScheme);
}
ChannelDataStore data = (ChannelDataStore)channel.ChannelData;
foreach (string uri in data.ChannelUris)
{
Console.WriteLine("URI: " + uri);
}
Console.WriteLine();
}

static void Main(string[] args)
{
// Create an TCP Channel
TcpServerChannel tcpChannel = new TcpServerChannel(8086);
ShowChannelProperties(tcpChannel);

// Create an HTTP Channel with a Binary Formatter
IDictionary properties = new Hashtable();
properties["name"] = "HTTP Channel with a Binary Formatter";
properties["priority"] = "15";
properties["port"] = "8085";
BinaryServerFormatterSinkProvider sinkProvider =
new BinaryServerFormatterSinkProvider();

HttpServerChannel httpChannel = new HttpServerChannel(
properties, sinkProvider);
ShowChannelProperties(httpChannel);

// Create an IPC Channel
IpcServerChannel ipcChannel = new IpcServerChannel("myIPCPort");
ShowChannelProperties(ipcChannel);

ChannelServices.RegisterChannel(tcpChannel);
ChannelServices.RegisterChannel(httpChannel);
ChannelServices.RegisterChannel(ipcChannel);

RemotingConfiguration.RegisterWellKnownServiceType(
typeof(Hello), "Hi", WellKnownObjectMode.SingleCall);
System.Console.WriteLine("press return to exit");
System.Console.ReadLine();

}
}
}


在工程属性中选择.net framework 4.0版本。



保存并编译之。

建立客户端工程:



和服务端一样,在引用中追加工程RemoteHello以及.net组件System.Runtime.Remoting。

客户端代码如下:

#region Using directives

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Activation;

#endregion

namespace Wrox.ProCSharp.Remoting
{
class Program
{
static void Main(string[] args)
{
ChannelServices.RegisterChannel(new TcpClientChannel());
Hello obj = (Hello)Activator.GetObject(
typeof(Hello), "tcp://localhost:8086/Hi");

//			ChannelServices.RegisterChannel(new System.Runtime.Remoting.Channels.Ipc.IpcClientChannel());
//			Hello obj = (Hello)Activator.GetObject(
//				typeof(Hello), "ipc://myIPCPort/Hi");

//			Hello obj = (Hello)RemotingServices.Connect(typeof(Hello),
//											"tcp://localhost:8086/Hi");
//
//			object[] attrs = { new UrlAttribute("tcp://localhost:8086/HelloServer") };
//
//			ObjectHandle handle = Activator.CreateInstance(
//						 "RemoteHello", "Wrox.ProCSharp.Remoting.Hello", attrs);
//			if (handle == null)
//			{
//				Console.WriteLine("could not locate server");
//				return;
//			}
//			Hello obj = (Hello)handle.Unwrap();
//			Console.WriteLine(obj.Greeting("Christian"));

if (obj == null)
{
Console.WriteLine("could not locate server");
return;
}

MySerialized ser = obj.GetMySerialized();
if (!RemotingServices.IsTransparentProxy(ser))
{
Console.WriteLine("ser is not a transparent proxy");
}
ser.Foo();
MyRemote rem = obj.GetMyRemote();
if (RemotingServices.IsTransparentProxy(rem))
{
Console.WriteLine("rem is a transparent proxy");
}
rem.Foo();

//			for (int i = 0; i < 5; i++)
//			{
//				Console.WriteLine(obj.Greeting("Christian"));
//			}

Console.ReadLine();
}
}
}


依次运行服务端和客户端,结果如下:

服务端:



客户端:



注意:

1.关于信道:

Net平台下服务器数据通信,支持多信道如:http,tcp,icp,自定义信道
http:默认情况下80端口未被防火墙通过。
tcp: 必须配置防火墙,在内部网中使用更加有效。
IPc:最适合在单个系统上进行跨进程的通信,使用WINDOWS跨进程通信机制,速度最快。

2.关于远程对象类:

远程对象类必须由System.MarshalByRefObject派生出来的。

相关技术资料:

/article/5711776.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: