[Mono-list] Listen on same port ipv4 and ipv6

J Decker d3ck0r at gmail.com
Fri Dec 11 23:51:50 UTC 2015


On Fri, Dec 11, 2015 at 3:25 PM, J Decker <d3ck0r at gmail.com> wrote:
> On Fri, Dec 11, 2015 at 2:33 PM, J Decker <d3ck0r at gmail.com> wrote:
>> On Fri, Dec 11, 2015 at 1:56 PM, J Decker <d3ck0r at gmail.com> wrote:
>>> On Fri, Dec 11, 2015 at 1:50 PM, J Decker <d3ck0r at gmail.com> wrote:
>>>> (First let me vent a little and say I LOVE all the consistency in
>>>> network libraries; in MS.NET closing a IPV6 TcpClient sets Client to
>>>> null, whereas IPV4 TcpCLient only disposes the object)
>>>>
>>>> I found this old message with no responses..
>>>>
>>>> http://lists.ximian.com/pipermail/mono-list/2014-May/050905.html
>>>>
>>>> I want to listen at the same port address at 0.0.0.0 and :: (ipv4 and
>>>> 6 address respectively)
>>>>
>>>> in C I would open two listeners.  But I think maybe the .NET runtime
>>>> is pre-checking if that port is already used in some internal list of
>>>> sockets before attemping to open it in reality.
>>>>
>>>> in C# I will have to do the same thing, since connecting to the v6
>>>> address with only the v4 listener at 0.0.0.0 listening fails to
>>>> connect and times out.
>>>>
>>>> On Windows I have to, and it works; but again with Mono on Linux it
>>>> doesn't work.
>>>
>>> This is the code that fails.
>>>
>>> internal GameServer()
>>> {
>>> byte[] raw_ipv4 = { 0, 0, 0, 0 };
>>> IPAddress addr = new IPAddress( raw_ipv4 );
>>> listener = new TcpListener( addr, Settings.Read( "Server Port",
>>> GameServer.serving_port ) );
>>> listener.Start();
>>> byte[] raw_ipv6 = { 0,0,0,0
>>> ,0, 0, 0, 0
>>> ,0, 0, 0, 0
>>> ,0, 0, 0, 0 };
>>> IPAddress addr_v6 = new IPAddress( raw_ipv6 );
>>> listener_v6 = new TcpListener( addr_v6, Settings.Read( "Server Port",
>>> GameServer.serving_port ) );
>>> listener_v6.Start(); /* Exception - EADDRINUSE ; even though it's not
>>> and needs to be opened */
>>> }
>
> Supposedly this is the fix.  (I checked my C code and remembered I was
> doing something with SetSockOpt)
> _Socket.SetSocketOption(SocketOptionLevel.Socket,
> SocketOptionName.ReuseAddress, True)
>
> But GetSocketOption returns 1 for reuse to start with... and setting
> it doesn't seem to do anything :(

System.Net.Sockets.SocketOptionName 0xf is not supported at Socket level

The SO_REUSEPORT socket option
https://lwn.net/Articles/542629/
"One of the features merged in the 3.9 development cycle was TCP and
UDP support for theSO_REUSEPORT socket option; that support was
implemented in a series of patches by Tom Herbert. The new socket
option allows multiple sockets on the same host to bind to the same
port, and is intended to improve the performance of multithreaded
network server applications running on top of multicore systems."

SO_REUSEPORT is 15 on SOL_SOCKET layer.

And of course 'convert_sockopt_level_and_name' is needed to go from
.NET defines to system values; and it doesn't allow passing arbitrary
values.

I guess... GetSocketOption for reuseaddr returns TRUE because it is
... it doesn't actually appear there's internal checking like I had
supposed, and they're all reflections from actual system error
codes...

is REUSEPORT 'needed' on newer linux kernels?  I don't quite
understand if it's for finer control or a requirment


More information about the Mono-list mailing list