获取.net远程支持IP v4和v6:如何将流映射到真正的ip,而不仅仅是参数异常

时间:2010-06-08 22:21:43

标签: c# .net remoting

我的公司有一个现有的.Net Remoting服务,可以向外部流程公开接口。我正在配置此服务以通过以下app.config部分支持IP v4和IP v6通信:

  <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远程处理中是不可能的吗?

2 个答案:

答案 0 :(得分:1)

我已经对此问题做了进一步的研究,并使用channel属性'machineName'以及'bindTo'找到了我的显式问题的解决方法(请参阅底部的配置文件部分)。

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

使用channel属性'machineName',服务被告知要绑定从api返回的流对象的ip地址。这样,客户端尝试访问流时,不是获取未知地址[::]异常,而是获取配置为与服务器配置的machineName对话的流对象。

使用channel属性'bindTo',服务被告知要侦听的IP地址以进行传入通信。这可以是显式ip,如下面的config部分所示,或者它可以是整个协议(IP [6的'[::]',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>

答案 1 :(得分:0)

我只是在Microsoft Connect网站上查找了这个http://connect.microsoft.com/VisualStudio/feedback/details/376712/net-remoting-tcpchannel-does-not-listen-on-ipv6

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

让我们看看其他人必须添加的内容。