让 .net 远程处理支持 IP v4 和 v6:如何将流映射到真实 IP,而不仅仅是参数异常

发布于 2024-09-04 15:40:00 字数 1588 浏览 8 评论 0原文

我的公司有一个现有的 .Net Remoting 服务,向外部进程公开接口。我通过以下 app.config 部分配置此服务以支持 IPv4 和 IPv6 通信:

  <system.runtime.remoting>
      <application>
        <service>
          <wellknown mode="Singleton" type="type,     
           dll"objectUri="exposedname.rem" />
        </service>
        <channels>
          <channel name="tcpclient" ref="tcp" encryption="EncryptAndSign">
            <clientProviders>
              <formatter ref="binary" />
            </clientProviders>
          </channel>
          <channel ref="tcp" name="tcp6" port="9000" bindTo="[::]" 
           encryption="EncryptAndSign">
            <clientProviders>
              <formatter ref="binary" />
            </clientProviders>
          </channel>
          <channel ref="tcp" name="tcp4" port="9000" bindTo="0.0.0.0"  
           encryption="EncryptAndSign">
            <clientProviders>
              <formatter ref="binary" />
            </clientProviders>
          </channel>
        </channels>
      </application>
      <customErrors mode="off"/>
  </system.runtime.remoting>

上述配置文件部分获取响应 ip v4 和 ip v6 上的非流功能的远程处理服务。但是,任何时候函数尝试发送或接收流时,都会引发以下 ArgumentException:

  IPv4 address 0.0.0.0 and IPv6 address ::0 are unspecified addresses that
  cannot be used as a target address.
  Parameter name: hostNameOrAddress

是否有办法修改 app.config,以便服务返回映射到真实 ip 的流并仍然支持 ip v4 和 ip v6?这在 .net 远程处理中不可能吗?

My company has an existing .Net Remoting service exposing interfaces to external processes. I am configuring this service to support both IP v4 and IP v6 communications by having the following app.config section:

  <system.runtime.remoting>
      <application>
        <service>
          <wellknown mode="Singleton" type="type,     
           dll"objectUri="exposedname.rem" />
        </service>
        <channels>
          <channel name="tcpclient" ref="tcp" encryption="EncryptAndSign">
            <clientProviders>
              <formatter ref="binary" />
            </clientProviders>
          </channel>
          <channel ref="tcp" name="tcp6" port="9000" bindTo="[::]" 
           encryption="EncryptAndSign">
            <clientProviders>
              <formatter ref="binary" />
            </clientProviders>
          </channel>
          <channel ref="tcp" name="tcp4" port="9000" bindTo="0.0.0.0"  
           encryption="EncryptAndSign">
            <clientProviders>
              <formatter ref="binary" />
            </clientProviders>
          </channel>
        </channels>
      </application>
      <customErrors mode="off"/>
  </system.runtime.remoting>

The above config file section gets the remoting service responding to non-stream functions on both ip v4 and ip v6. Any time a function tries to send or receive a stream, however, the following ArgumentException is thrown:

  IPv4 address 0.0.0.0 and IPv6 address ::0 are unspecified addresses that
  cannot be used as a target address.
  Parameter name: hostNameOrAddress

Is there a way to modify the app.config so that the service will return a stream mapped to a real ip and still support ip v4 and ip v6? Is this not possible in .net remoting?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

看海 2024-09-11 15:40:00

我对这个问题做了进一步的研究,并找到了使用通道属性“machineName”和“bindTo”来解决我的显式问题的解决方法(请参阅底部的配置文件部分)。

在我的明确情况下,我不需要同时支持来自 ip v4 和 ip v6 的连接,因为通过配置,连接只会来自两个 ip 版本之一。因此,下面的配置部分仅详细介绍如何设置 .net 远程服务以通过 IPv6 进行完全通信。我相信这个配置修复可以让服务响应 ip v4 和 ip v6 通信,但是我还没有测试它,所以我不确定。

使用通道属性“machineName”,服务被告知将从 api 返回的流对象绑定到哪个 IP 地址。这样,当客户端尝试访问流时,客户端不会获得未知地址 [::] 异常,而是会获得一个配置为与服务器配置的 machineName 进行对话的流对象。

使用通道属性“bindTo”,服务被告知要侦听传入通信的 IP 地址。这可以是显式 ip,如下面的配置部分所示,也可以是整个协议(对于 IPv6 为“[::]”,对于 ip v4 为“0.0.0.0”)。如果您不使用 ip v6,而只使用 ip v4,则仅当您希望将服务锁定到一个显式 ip 时才需要此属性。否则,由于 .Net 远程处理会自动采用 ip v4,因此它将正常工作。

希望这对其他使用 ip v4/v6 的人有一点帮助。

  <system.runtime.remoting>
      <application>
        <service>
          <wellknown mode="Singleton" type="Kryptiq.Partners.Service.PartnersServiceApi, KPtnrSvc" objectUri="KPtnrSvc.rem" />
        </service>
        <channels>
          <channel name="tcpclient" ref="tcp" encryption="EncryptAndSign" 
           machineName="[fe80::839:c79e:141a:2498%15]">
            <clientProviders>
              <formatter ref="binary" />
            </clientProviders>
          </channel>
          <channel name="tcpserver" ref="tcp" port="2500" encryption="EncryptAndSign"
           machineName="[fe80::839:c79e:141a:2498%15]" 
           bindTo="[fe80::839:c79e:141a:2498%15]">
            <serverProviders>
              <formatter ref="binary" />
            </serverProviders>
          </channel>
        </channels>
      </application>
  </system.runtime.remoting>

I have done further research on this issue, and have found a workaround for my explicit issue using the channel attribute 'machineName' as well as 'bindTo' (see the the config file section at the bottom).

In my explicit case, I do not need to support connections coming in from both ip v4 and ip v6 at the same time since by configuration, the connections will only be coming in on one of the two ip versions. As such, the config section below only details setting up a .net remoting service to fully communicate over IP v6. I believe this config fix would work to get the service responding to both ip v4 and ip v6 communication, however I have not tested it so I don't know for sure.

Using the channel attribute 'machineName', the service is told what ip address to bind a stream object returned from the api to. This way, rather than getting an unknown address [::] exception when the client tries to access the stream, the client gets a stream object configured to talk back to the server's configured machineName.

Using the channel attribute 'bindTo', the service is told what ip address to listen on for incoming communication. This can be an explicit ip, as shown in the below config section, or it can be a whole protocol ('[::]' for IP v6, '0.0.0.0' for ip v4). If you're not doing ip v6, but only ip v4, this attribute is only needed if you wish to lock your service down to one explicit ip. Otherwise, as .Net remoting automatically assumes ip v4, it will just work right.

Hope this helps others with ip v4/v6 a little.

  <system.runtime.remoting>
      <application>
        <service>
          <wellknown mode="Singleton" type="Kryptiq.Partners.Service.PartnersServiceApi, KPtnrSvc" objectUri="KPtnrSvc.rem" />
        </service>
        <channels>
          <channel name="tcpclient" ref="tcp" encryption="EncryptAndSign" 
           machineName="[fe80::839:c79e:141a:2498%15]">
            <clientProviders>
              <formatter ref="binary" />
            </clientProviders>
          </channel>
          <channel name="tcpserver" ref="tcp" port="2500" encryption="EncryptAndSign"
           machineName="[fe80::839:c79e:141a:2498%15]" 
           bindTo="[fe80::839:c79e:141a:2498%15]">
            <serverProviders>
              <formatter ref="binary" />
            </serverProviders>
          </channel>
        </channels>
      </application>
  </system.runtime.remoting>
山人契 2024-09-11 15:40:00

我刚刚查了这个 http://connect.microsoft.com/VisualStudio/feedback/details/376712/net-remoting-tcpchannel-does-not-listen-on-ipv6(位于 Microsoft Connect 站点)。

看起来 IPV6 只能在没有 IPV4 的情况下工作,根据该帖子,这是设计使然。

让我们看看其他人必须添加什么。

I just looked up this one http://connect.microsoft.com/VisualStudio/feedback/details/376712/net-remoting-tcpchannel-does-not-listen-on-ipv6 at Microsoft Connect site.

It looks like IPV6 will only work in the absence of IPV4 and this according to the post is by design.

Lets see what others have to add to it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文