use*_*406 5 .net c# connection remoting
.Net Remoting是打开多个连接还是只打开一个连接?假设我有一台服务器和一台客户端.如果客户端创建多个SingleCall对象.那么对于每个对象,是否会有一个新的连接,或者每个对象都会有一个连接?
我无法在任何地方找到答案.
答案很长:这取决于很多事情.简短的回答是肯定的.是的是的.
让我们做一个实验,看看最常见的默认情况.我们有2个控制台应用程序和1个通用类库,由两个控制台应用程序引用.第一个控制台应用程序具有客户端的角色,第二个控制台应用程序具有服务器的角色.
首先,这是通常依赖于类库的内容:
public interface IFactory {
string Hello(string name);
}
Run Code Online (Sandbox Code Playgroud)
现在为一些服务器代码.这是启动:
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);
}
Run Code Online (Sandbox Code Playgroud)
我们刚刚提到了一个名为Factory的类.
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Factory), "Factory.rem", WellKnownObjectMode.SingleCall);
Run Code Online (Sandbox Code Playgroud)
你猜到了.这是IFactory的实现:
private sealed class Factory : MarshalByRefObject, IFactory {
#region IFactory Members
string IFactory.Hello(string name) {
return @"Hello " + name + @" !";
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
现在为一些客户:
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);
}
Run Code Online (Sandbox Code Playgroud)
你已经知道所有这些事情了,我敢肯定.我们在另一侧获得了SingleCall服务的透明代理(它们都在同一台机器上,我们使用的是TCP端口2013):
IFactory factory = Activator.GetObject(typeof(IFactory), @"tcp://127.0.0.1:2013/Factory.rem") as IFactory;
Run Code Online (Sandbox Code Playgroud)
然后,出于"同时性"的原因,我们创建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();
Run Code Online (Sandbox Code Playgroud)
因此,虽然已经创建并启动了所有100个线程,但它们都在以下调用中等待:
signal.WaitOne();
Run Code Online (Sandbox Code Playgroud)
这样我们可以更好地同时启动,否则线程本身的创建和启动会使其实际执行或多或少地顺序执行.
我们要求用户决定何时使用100个Hello调用"轰炸服务器":
Console.WriteLine("Press any key to bombard server...");
Console.ReadKey(intercept: true);
signal.Set();
Run Code Online (Sandbox Code Playgroud)
这就是发生的事情:
1)我们启动服务器控制台应用程序,让它运行平安:

2)我们启动客户端控制台应用程序,通过按任意键"进行连接"(这只是一个逻辑连接,因为它只是创建一个透明代理)但我们推迟了"轰炸":

3)我们启动Mark Russinovich的Process Explorer并使用它来发现进程列表中的客户端进程,并在执行此操作时打开它的属性窗口并选择TCP/IP选项卡:

4)我们点击客户端控制台应用程序中的任何键,然后.. TA DAA !! 您在Process Explorer中获得了大量连接.他们是百?有时是,有时没有.这是一个连接池,这是肯定的.在短暂停留(5到10秒)之后,它们关闭了,这是一件非常好的事情(因为.NET Remoting堆栈是以这种方式实现的).

我希望这个实验能够回答你的问题.
在更具体的情况下,在更严格的意义上,您应该查看文档并阅读您可能在.NET Remoting应用程序中使用的各种渠道(其中有很多,你在这里看到的只是由Microsoft正式提供的常规TcpChannel,它取决于您的.NET Remoting配置所说的内容,关于您是否在IIS中托管服务器等).
网络连接的数量取决于您使用的远程处理通道。默认 TcpChannel 打开的网络连接数量与程序中在某个时间点尝试访问服务器的线程数量相同。
对于单线程应用程序,TcpChannel 使用一个网络连接。
作为一个相反的示例,第三方远程处理通道IiopChannel使用多路复用,因此允许仅为数百个活动线程提供几个网络连接。
| 归档时间: |
|
| 查看次数: |
2893 次 |
| 最近记录: |