原文地址:http://blog.csdn.net/chengking/archive/2005/10/26/517349.aspx
(一).說明
??? 一個遠程調用示例.
??? 此示例實現功能: 客房端調用遠程方法(遠程方法可以彈??? 出自定義信息),實現發送信息功能.
??? 實現原理概是這樣的:客戶端不能直接調用遠程對象,它必須先通過信道請求服務端宿主程序,當收到客戶端請求時,
??? .net遠程處理框架會在宿主組件的應用程序域中生成所需要的遠程對象. 并執行遠程對象中的方法.????
(二).實現方案
在之前先介紹幾種類:
??? 1.可序列化的類: 以<serializable>屬性為標記,可以在進程/應用程序/計算機之間傳送.
??? 2.可遠程調用的類: 直接或間接地繼承 System.MarshalByRefObject類,可以被遠程激活.
??? 3.一般類:???????? 不能構建分布式,用于本地調用.
1.首先建立三個項目:
??? RemoteObject: 提供遠程對象,供客戶端調用
??? SimpleClient: 用于向服務端程序發出請求,調用遠程對象 (winform)
??? SimpleServer: 偵聽客戶端請求,并創建對象???????????? (winform)
2.在RemoteObject項目下面建立遠程調用類: RemoteObject.cs
??? 在SimpleClient項目下面建立: Form1.cs和SimpleClient.exe.config配置文件。
????????? 其中配置文件的作用是指定服務端地址和信道等信息,下面的代碼里面有詳細說明.
??? 在SimpleServer項目下面建立: Form1.cs和SimpleServer.exe.config配置文件。
????????? 其中配置文件的作用是指定接受請求客戶端的地址和信道等信息,下面的代碼里面有詳細說明.
(三).
各文件源代碼:
1.RemoteObject.cs
??? using System;
??? using System.Windows.Forms;
??? namespace RemoteObjects
??? {
public class RemoteObject : System.MarshalByRefObject //繼承此類才能被遠程激活調用
{
?? public RemoteObject()
?? {
?? }
??
?? //遠程調用方法,功能: 彈出自定義消息, 參數: str是從客戶端傳遞過來的
?? public static void Method(string str)
?? {???
?????????????????? MessageBox.Show(str);???
?? }??
}
??? }
2.客戶端工程SimpleClient項目中的Form1.cs:
??? using System;
??? using System.Drawing;
??? using System.Collections;
??? using System.ComponentModel;
??? using System.Windows.Forms;
??? using System.Data;
??? using RemoteObjects;
??? namespace SimpleClient
??? {
public class Form1 : System.Windows.Forms.Form
{
?? private System.Windows.Forms.TextBox textBox1;
?? private System.Windows.Forms.Label label1;
?? private System.Windows.Forms.Button button1;??
?? private System.ComponentModel.Container components = null;
?? public Form1()
?? {???
??? InitializeComponent();
?? }??
?? protected override void Dispose( bool disposing )
?? {
??? if( disposing )
??? {
???? if (components != null)
???? {
????? components.Dispose();
???? }
??? }
??? base.Dispose( disposing );
?? }
?? #region Windows 窗體設計器生成的代碼
?? /// <summary>
?? /// 設計器支持所需的方法 - 不要使用代碼編輯器修改
?? /// 此方法的內容。
?? /// </summary>
?? private void InitializeComponent()
?? {
??? this.textBox1 = new System.Windows.Forms.TextBox();
??? this.label1 = new System.Windows.Forms.Label();
??? this.button1 = new System.Windows.Forms.Button();
??? this.SuspendLayout();
??? //
??? // textBox1
??? //
??? this.textBox1.Location = new System.Drawing.Point(40, 88);
??? this.textBox1.Multiline = true;
??? this.textBox1.Name = "textBox1";
??? this.textBox1.Size = new System.Drawing.Size(336, 176);
??? this.textBox1.TabIndex = 0;
??? this.textBox1.Text = "";
??? //
??? // label1
??? //
??? this.label1.Location = new System.Drawing.Point(40, 32);
??? this.label1.Name = "label1";
??? this.label1.TabIndex = 1;
??? this.label1.Text = "請輸入信息:";
??? //
??? // button1
??? //
??? this.button1.Location = new System.Drawing.Point(296, 32);
??? this.button1.Name = "button1";
??? this.button1.TabIndex = 2;
??? this.button1.Text = "發送";
??? this.button1.Click += new System.EventHandler(this.button1_Click);
??? //
??? // Form1
??? //
??? this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
??? this.ClientSize = new System.Drawing.Size(416, 302);
??? this.Controls.Add(this.button1);
??? this.Controls.Add(this.label1);
??? this.Controls.Add(this.textBox1);
??? this.Name = "Form1";
??? this.Text = "發送信息";
??? this.Load += new System.EventHandler(this.Form1_Load);
??? this.ResumeLayout(false);
?? }
?? #endregion
??
?? [STAThread]
?? static void Main()
?? {
??? Application.Run(new Form1());???
?? }
??
?? private void Form1_Load(object sender, System.EventArgs e)
?? {
????? //載入信道,用于偵聽客戶端請求,配置文件記載客戶端地址等信息.
??? System.Runtime.Remoting.RemotingConfiguration.Configure("Simpleclient.exe.config");???
?? }
?? private void button1_Click(object sender, System.EventArgs e)
?? {
??? //開始調用遠程對象(發送信息)
??? RemoteObjects.RemoteObject.Method(this.textBox1.Text);
?? }
}
??? }
3.客戶端工程SimpleClient項目中的SimpleClient.exe.config:
?? <?xml version="1.0" encoding="utf-8" ?>
?? <configuration>
<system.runtime.remoting>
?? <application name="simpleclient">
??? <!-- 指定請求的服務端地址和端口號-->
??? <!-- url中的:localhost是測試的本機,可以使用Intenet上的其它機器名或ip地址-->
??? <client url="tcp://localhost:8080/simpleserver">
???? <activated type="RemoteObjects.RemoteObject,RemoteObjects">
???? </activated>
??? </client>
??? <channels>
???? <!-- 指定信道,有兩種信道可選:Tcp(基于TCP協議)和Http(無連續連接協議)信道-->
???? <channel ref="tcp client"/>??
??? </channels>
?? </application>
</system.runtime.remoting>
??? </configuration>
4.服務端工程SimpleServer項目中的Form1.cs:
?? using System;
?? using System.Drawing;
?? using System.Collections;
?? using System.ComponentModel;
?? using System.Windows.Forms;
?? using System.Data;
?? using System.Runtime.Remoting;
?? namespace SimpleServer
?? {
/// <summary>
/// Form1 的摘要說明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
?? /// <summary>
?? /// 必需的設計器變量。
?? /// </summary>
?? private System.ComponentModel.Container components = null;
?? public Form1()
?? {
??? //
??? // Windows 窗體設計器支持所必需的
??? //
??? InitializeComponent();
??? //
??? // TODO: 在 InitializeComponent 調用后添加任何構造函數代碼
??? //
?? }
?? /// <summary>
?? /// 清理所有正在使用的資源。
?? /// </summary>
?? protected override void Dispose( bool disposing )
?? {
??? if( disposing )
??? {
???? if (components != null)
???? {
????? components.Dispose();
???? }
??? }
??? base.Dispose( disposing );
?? }
?? #region Windows 窗體設計器生成的代碼
?? /// <summary>
?? /// 設計器支持所需的方法 - 不要使用代碼編輯器修改
?? /// 此方法的內容。
?? /// </summary>
?? private void InitializeComponent()
?? {
??? //
??? // Form1
??? //
??? this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
??? this.ClientSize = new System.Drawing.Size(292, 266);
??? this.Name = "Form1";
??? this.Text = "Form1";
??? this.Load += new System.EventHandler(this.Form1_Load);
?? }
?? #endregion
?? /// <summary>
?? /// 應用程序的主入口點。
?? /// </summary>
?? [STAThread]
?? static void Main()
?? {
??? //Application.Run(new Form1());???
??? Run();
?? }
?? private static void Run()
?? {
??? System.Runtime.Remoting.RemotingConfiguration.Configure("SimpleServer.exe.config");
?? }
?? private void Form1_Load(object sender, System.EventArgs e)
?? {
???
?? }
?? }
??? }
5.服務端工程SimpleServer項目中的SimpleServer.exe.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
?? <application name="simpleserver">
??? <service>
???? <activated type="RemoteObjects.RemoteObject,RemoteObjects">
???? </activated>
??? </service>
??? <channels>
???? <channel ref="tcp server" port="8080" />
??? </channels>
?? </application>
</system.runtime.remoting>
</configuration>
(四).注意點
?? 1.由于配置文件默認是添加在根目錄下的,要把兩個配置文件拷貝到:根目錄/bin/debug下面,要讓它與執行文件在同一個目錄下面。
?? 2.右擊RemoteObject項目,選“常規”下的,輸入類型為:“類庫”. 它默認為應用程序,這里作為類庫使用.
???? 設置好后,按: Ctrl+Shift+B生成類庫Dll.
?? 3.在工程SimpleServer和SimpleClient中分別添加引用: 即將RemoteObject項目剛生成的DLL: RemoteObjects.dll添加到各自的工程中.
???? 具體方法:右擊“引用“->”添加引用“->"瀏覽",找到生成的RemoteObjects.dll分別添加進來.
?? 4.右擊解決方案,選擇“屬性”-> “選中多啟動項目單選框”->"選SimpleServer和SimpleClient同時啟動".
???? 因為: 當服務端宿主程序運行時,客戶端才能正確調用遠程對象.
?? 5.按F5運行. 輸入信息,點“發送”按鈕,就可以調用遠程對象了.
(五).擴展
???? 可以修改客戶端配置文件:<client url="tcp://localhost:8080/simpleserver"> 中的localhost為其它的機器名稱,只要另一臺
???? 機器運行了宿主程序,并處于運行狀態. 那么當調用時,會在服務端彈出信息,即實現了發送信息功能.
?
以上代碼已經測試,不正確的地方望批評指正!