Getting .net remoting to support IP v4 and v6: how to get a stream mapped to a real ip, not just an argument exception
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?
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>
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.
精彩评论