天天看點

HOW TO:使用 Visual C# .NET 按值将對象封送到遠端伺服器 (From MSDN)

本文的釋出号曾為 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 類。

  1. 打開 Visual Studio .NET。
  2. 建立一個 Visual C# .NET 類庫應用程式。預設情況下建立 Class1.cs。
  3. 在解決方案資料總管中,将 Class1.cs 檔案重命名為 ServerClassValue.cs。
  4. 打開 ServerClassValue.cs。導入 System.Diagnostics 名稱空間,這樣,以後就不需要在代碼中完全限定名稱了。
    using System;
    using System.Diagnostics;      
  5. 添加兩個類,即 HelloServer 和 ForwardMe。 HelloServer 是從 MarshalByRefObject 類繼承的,而且 ForwardMe 類使用 <Serializable> 自定義屬性。 在将對象按值傳遞到遠端伺服器時,此标記允許将 ForwardMe 類以流的形式輸入和輸出伺服器。

    HelloServer 是客戶機應用程式使用的主類。ForwardMe 用來将對象資料從客戶機發送到伺服器。 因為 ForwardMe 不是從 MarshalByRefObject 繼承的,是以将它按值傳遞到伺服器。

    public class HelloServer : MarshalByRefObject
    {
    }
    
    [Serializable]
    public class ForwardMe
    {
    }      
  6. 将公用方法 HelloMethod 添加到 HelloServer,後者将 ForwardMe 對象作為參數。 使用此方法将 ForwardMe 對象傳遞到伺服器。此方法調用這一對象的 CallMe 方法。您的 HelloServer 類現在應該如下所示:
    public class HelloServer : MarshalByRefObject
    {
    	public void HelloMethod(ForwardMe obj )
    	{
               obj.CallMe();
    	}
    }       
  7. 将一個公用方法添加到 ForwardMe 類,并根據執行此代碼的程序來命名此方法。 因為您将整個對象序列化傳遞到伺服器(按值封送),是以此代碼在伺服器的程序中運作。
    [Serializable]
    public class ForwardMe
    {
    	public void CallMe() 
    	{
    		 Console.WriteLine("CallMe was executed in: " +
    			Process.GetCurrentProcess().ProcessName.ToString());
    	}							
    }      
  8. 生成該項目以建立 ServerClassValue.dll 程式集。
  9. 儲存并關閉該項目。

傳回頁首

建立遠端伺服器應用程式

在建立了客戶機将與之通訊的伺服器對象後,必須将此對象注冊到遠端處理架構中。注冊不僅包括對對象進行注冊,還包括啟動伺服器并讓它偵聽一個端口以便客戶機進行連接配接。為此,您需要一個能建立可執行檔案的項目類型。 将伺服器對象包含在另一個項目中,以便能友善地從客戶機引用伺服器對象。如果您在此項目中包括了伺服器對象,您不能引用它,因為隻可以設定到 DLL 檔案的引用。

  1. 打開 Visual Studio .NET。
  2. 建立一個 Visual C# .NET 控制台應用程式以啟動遠端伺服器。預設情況下建立 Class1.cs。
  3. 在解決方案資料總管中,将 Class1.cs 檔案重命名為 ServerObjectValue.cs。
  4. 給項目添加一個到 System.Runtime.Remoting 名稱空間的引用。
  5. 添加對 ServerClassValue.dll 程式集(在建立遠端伺服器對象一節中建立的)的引用。
  6. 對 Remoting、Remoting.Channels 和 Remoting.Channels.Tcp 名稱空間使用 using 語句,這樣,在後面的代碼中就不需要限定這些名稱空間中的聲明了。using 語句必須位于所有其他聲明之前。
    using System.Runtime.Remoting;
    using System.Runtime.Remoting.Channels;
    using System.Runtime.Remoting.Channels.Tcp;      
  7. 聲明相應的變量以初始化一個 TcpChannel 對象,該對象監聽某個端口以便客戶機進行連接配接(本例中為 8085 端口)。使用 RegisterChannel 方法注冊客戶機将用來與通道服務進行通訊的通道。在 Module1 的 Main 過程中添加聲明代碼:
    TcpChannel chan = new TcpChannel(8085);
    ChannelServices.RegisterChannel(chan);      
  8. 調用 RemotingConfiguration 對象的 RegisterWellKnownType 方法,将 ServerClassValue 對象注冊到遠端處理架構中。在代碼中必須指定下列參數:
    1. 正在注冊的對象的完整類型名稱(本例中是 ServerClassValue.HelloServer),後面跟着程式集名稱 ServerClassValue。必須指定名稱空間的名稱和類名。因為在前面的部分中沒有指定名稱空間,是以使用預設的根名稱空間。
    2. 對象将要釋出到的終結點的名稱。客戶機需要知道此名稱以便連接配接到該對象。 請使用 RemoteTestValue。
    3. 對象模式,可以是 SingleCall 或 Singleton。本例指定 SingleCall。對象模式指定了在伺服器上激活該對象時的有效期。對于 SingleCall 對象,針對客戶機的每次調用都會建立類的一個新執行個體,即使在同一客戶機多次調用同一方法的情況下也是如此。或者,隻建立一次 Singleton 對象,所有客戶機都與同一個對象通訊。
    RemotingConfiguration.RegisterWellKnownServiceType(
    	Type.GetType("ServerClassValue.HelloServer, ServerClassValue"),
    	"RemoteTestRef",
    	WellKnownObjectMode.SingleCall);      
  9. 使用 Console 對象的 ReadLine 方法保持伺服器應用程式的運作:
    Console.WriteLine("Press <ENTER> to exit...");
    Console.ReadLine();       
  10. 生成項目。
  11. 儲存并關閉項目。

傳回頁首

建立客戶機應用程式

  1. 打開 Visual Studio .NET。
  2. 在 Visual C# .NET 中建立控制台應用程式。預設情況下建立 Class1.cs。
  3. 在解決方案資料總管中,将 Class1.cs 檔案重命名為 ClientAppValue.cs。
  4. 給項目添加一個到 System.Runtime.Remoting 名稱空間的引用。
  5. 添加對 ServerClassValue.dll 程式集(在建立遠端伺服器對象一節中建立的)的引用。
  6. 對 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;      
  7. 聲明相應的變量以初始化一個 TcpChannel 對象,客戶機将使用該對象連接配接到伺服器應用程式。使用 RegisterChannel 方法将該通道注冊到通道服務。

    然後,必須初始化一個新的 ForwardMe 對象,該對象将被傳遞到遠端伺服器對象。 切記,将按值傳遞該對象。在 Module1 的 Main 過程中添加聲明代碼:

    TcpChannel chan = new TcpChannel();
    ChannelServices.RegisterChannel(chan);
    ForwardMe objForwardMe  = new ForwardMe();      
  8. 聲明和執行個體化遠端伺服器。在本例中,使用 Activator 對象的 GetObject 方法執行個體化 HelloServer 對象。在代碼中必須指定下列參數:
    1. 正在注冊的對象的完整類型名稱(本例中是 ServerClassValue.HelloServer),後面跟着程式集名稱 ServerClassValue。必須指定名稱空間的名稱和類名。因為在前面的部分中沒有指定名稱空間,是以使用預設的根名稱空間。
    2. 要激活的對象的統一資源辨別符 (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
    }       
  9. 如果伺服器對象執行個體化成功,則調用伺服器對象的 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.");
    }      
  10. 使用 Console 對象的 ReadLine 方法保持客戶機應用程式的運作:
    Console.WriteLine("Press <ENTER> to exit...");
    Console.ReadLine();       
  11. 生成項目。
  12. 確定伺服器應用程式在運作中。
  13. 運作客戶機項目以測試客戶機和伺服器之間的通訊。

運作客戶機時,當該方法執行結束時,您就會收到通知。 注意, 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