.Net Remoting是否打開多個連接或只有一個? 讓我說我有一個服務器和一個客戶端。如果客戶端創建多個SingleCall對象。那麼對於每一個對象都會有一個新的連接,或者每個對象都會有一個連接?.Net Remoting只使用一個連接?
我無法在任何地方找到答案。
.Net Remoting是否打開多個連接或只有一個? 讓我說我有一個服務器和一個客戶端。如果客戶端創建多個SingleCall對象。那麼對於每一個對象都會有一個新的連接,或者每個對象都會有一個連接?.Net Remoting只使用一個連接?
我無法在任何地方找到答案。
網絡連接的數量取決於您使用的遠程處理通道。默認的TcpChannel打開儘可能多的網絡連接,程序中的許多線程在一個時間點嘗試訪問服務器。
對於單線程應用程序,TcpChannel使用一個網絡連接。
作爲一個相反的例子,第三方遠程處理通道IiopChannel使用了多路複用,因此可以爲幾百個活動線程提供幾個網絡連接。
長的答案是:它取決於很多事情。 簡短答案是肯定的。是的是的。
讓我們做一個實驗,看看最常見的默認情況。 我們有兩個控制檯應用程序和一個通用類庫,這兩個控制檯應用程序都會引用它們。 第一個控制檯應用程序具有客戶端角色,第二個控制檯應用程序具有服務器角色。
首先,這裏就是常用依賴於類庫包含:
public interface IFactory {
string Hello(string name);
}
現在對於一些服務器代碼。這裏的啓動:
private static TcpChannel channel;
static void Main(string[] args) {
BinaryClientFormatterSinkProvider clientProv = new BinaryClientFormatterSinkProvider();
BinaryServerFormatterSinkProvider serverProv = new BinaryServerFormatterSinkProvider();
serverProv.TypeFilterLevel = TypeFilterLevel.Full;
channel = new TcpChannel(
properties: new Hashtable {
{ @"port", 2013 }
},
clientSinkProvider: clientProv,
serverSinkProvider: serverProv
);
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Factory), "Factory.rem", WellKnownObjectMode.SingleCall);
Console.WriteLine("Server started...");
Console.WriteLine("Press any key to stop...");
Console.ReadKey(intercept: true);
}
我們剛纔提到了一個名爲廠類。
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Factory), "Factory.rem", WellKnownObjectMode.SingleCall);
你猜對了。這是IFactory的實現:
private sealed class Factory : MarshalByRefObject, IFactory {
#region IFactory Members
string IFactory.Hello(string name) {
return @"Hello " + name + @" !";
}
#endregion
}
現在,某些客戶端:
static void Main(string[] args) {
Console.WriteLine("Press any key to connect...");
Console.ReadKey(intercept: true);
IFactory factory = Activator.GetObject(typeof(IFactory), @"tcp://127.0.0.1:2013/Factory.rem") as IFactory;
EventWaitHandle signal = new EventWaitHandle(initialState: false, mode: EventResetMode.ManualReset);
ThreadStart action =() => {
signal.WaitOne();
var result = factory.Hello("Eduard");
Console.WriteLine(result);
};
foreach (var i in Enumerable.Range(0, 99))
new Thread(action) { IsBackground = true }.Start();
Console.WriteLine("Press any key to bombard server...");
Console.ReadKey(intercept: true);
signal.Set();
Console.ReadKey(intercept: true);
}
你已經知道所有這些事情,我敢肯定。我們得到了一個透明代理到另一側的SingleCall服務(他們都在同一臺機器上,我們正在使用TCP端口2013):
IFactory factory = Activator.GetObject(typeof(IFactory), @"tcp://127.0.0.1:2013/Factory.rem") as IFactory;
然後,我們創建「simulataneous性」的原因100個線程,啓動它們(這可能需要一些時間),但「它們保持在皮帶」(一個信號是操作系統的同步的重要手段),直到我們「扣動扳機」:
EventWaitHandle signal = new EventWaitHandle(initialState: false, mode: EventResetMode.ManualReset);
ThreadStart action =() => {
signal.WaitOne();
var result = factory.Hello("Eduard");
Console.WriteLine(result);
};
foreach (var i in Enumerable.Range(0, 99))
new Thread(action) { IsBackground = true }.Start();
所以儘管已創建全部100個線程和,但它們都在等待以下調用:
signal.WaitOne();
這樣,我們可以得到在同一時間更好啓動,否則線程的創建和啓動本身會作出自己的實際執行或多或少的順序。
我們要求用戶來決定何時與100你好調用「炮轟服務器」:
Console.WriteLine("Press any key to bombard server...");
Console.ReadKey(intercept: true);
signal.Set();
這是發生了什麼:
1)我們開始服務器控制檯應用程序和讓它在和平運行:
2)我們開始客戶控制檯應用程序「進行連接」按任意鍵(這是唯一的邏輯連接,因爲它僅僅是創建一個透明的代理),但我們推遲了「轟炸」:
3)我們啓動馬克Russinovich的Process Explorer,並用它來發現客戶進程在進程列表中,並同時做,我們打開它的屬性窗口,選擇TCP/IP選項卡:
4)我們打了客戶端控制檯應用程序中的任意鍵,並且.. TA DAA !! 你得到很多連接Process Explorer。 他們是一百呢?有時是的,有時沒有。 這是一個連接池,這是肯定的。 經過一段時間(5到10秒)的空閒,它們關閉,這是一件非常好的事情(因爲.NET Remoting堆棧是以這種方式實現的)。
我希望這個實驗一般回答你的問題。
在更具體的情況下,您應該查看文檔並瞭解您可能在.NET Remoting應用程序中使用的各種渠道(其中有大量的渠道,您看過的內容這裏只是微軟官方提供的常規TcpChannel,它取決於你的.NET Remoting配置說什麼,你是否在IIS中託管服務器等等)。
這是一個絕對美麗的答案。謝謝! – Quibblesome 2017-07-19 07:37:29
我認爲這取決於使用什麼渠道,但*爲什麼*你在2013年編寫遠程代碼? – 2013-02-21 07:24:01
@Damien_The_Unbeliever他可能正在做一箇舊項目。你的意思是什麼取決於頻道?渠道決定? – m1o2 2013-02-21 08:15:16