C# .Net远程处理仅使用一个连接?

C# .Net远程处理仅使用一个连接?,c#,.net,remoting,connection,C#,.net,Remoting,Connection,.Net远程处理是打开多个连接还是只打开一个连接? 假设我有一个服务器和一个客户端。如果客户端创建多个SingleCall对象。那么对于每个对象,是有一个新的连接,还是每个对象都有一个单独的连接 我到处都找不到答案。长的答案是:这取决于很多事情。 简而言之,答案是肯定的。对对 让我们做一个实验,看看最常见的默认情况。 我们有两个控制台应用程序和一个公共类库,这两个控制台应用程序都引用了它们。 第一个控制台应用程序具有客户端角色,第二个控制台应用程序具有服务器角色 首先,这里是通常依赖的类库包含的

.Net远程处理是打开多个连接还是只打开一个连接? 假设我有一个服务器和一个客户端。如果客户端创建多个SingleCall对象。那么对于每个对象,是有一个新的连接,还是每个对象都有一个单独的连接


我到处都找不到答案。

长的答案是:这取决于很多事情。 简而言之,答案是肯定的。对对

让我们做一个实验,看看最常见的默认情况。 我们有两个控制台应用程序和一个公共类库,这两个控制台应用程序都引用了它们。 第一个控制台应用程序具有客户端角色,第二个控制台应用程序具有服务器角色

首先,这里是通常依赖的类库包含的内容:

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):

然后,出于“模拟性”的原因,我们创建了100个线程,启动它们(这可能需要一些时间),但在我们“扣动触发器”之前,“将它们拴在皮带上”(信号是操作系统同步的基本手段):

因此,尽管所有100个线程都已创建并启动,但它们都在等待以下调用:

signal.WaitOne();
这样我们可以让线程同时启动,更好地启动,否则线程本身的创建和启动会使它们的实际执行或多或少具有顺序性

我们要求用户决定何时使用100次Hello调用“轰炸服务器”:

Console.WriteLine("Press any key to bombard server...");
Console.ReadKey(intercept: true);

signal.Set();
事情就是这样的:

1) 我们启动服务器控制台应用程序,让它和平运行:

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

3) 我们启动Mark Russinovich,并使用它来发现流程列表中的客户端流程,同时打开其属性窗口并选择TCP/IP选项卡:

4) 我们点击客户端控制台应用程序中的任意键,然后TA DAA 你在网络中获得了大量的联系。 他们是一百吗?有时是,有时不是。 这是一个连接池,这是肯定的。 在短暂的空闲时间(5到10秒)后,它们会关闭,这是一件非常好的事情(因为.NET远程处理堆栈就是这样实现的)

我希望这个实验大体上回答了你的问题


在更具体的情况下,在更严格的意义上,您应该查看文档,并阅读您可能在.NET远程处理应用程序中使用的各种渠道(有很多,你在这里看到的只是微软官方提供的常规TCP频道,这取决于你的.NET远程处理配置,取决于你是否在IIS中托管服务器,等等).

网络连接的数量取决于您使用的远程处理通道。默认TCP通道打开的网络连接数量与您的程序中在一个时间点尝试访问服务器的线程数量相同

对于单线程应用程序,TCP通道使用一个网络连接


另一个相反的例子是,第三方远程处理通道使用多路复用,因此允许数百个活动线程只需几个网络连接。

我认为这取决于哪个通道正在使用,但你为什么要在2013年编写远程处理代码?@Damien_不信者他可能正在从事一个旧项目。你说这取决于频道是什么意思?频道决定这一点?这是一个绝对漂亮的答案。谢谢!
signal.WaitOne();
Console.WriteLine("Press any key to bombard server...");
Console.ReadKey(intercept: true);

signal.Set();