Listen on both IPv4 and IPv6

I’m trying to listen on both IPv4 and IPv6.

  ear4=listen(IPv4(0),port)
  ear6=listen(IPv6(0),port)

This resulted in IOError: listen: address already in use (EADDRINUSE) on the IPv6 line. I’m running Linux, and if I remember right from many years ago when I tried in C or C++ to do some networking, listening on IPv6 also listens on IPv4, but on BSD (I tried DragonFly) it doesn’t.

How should I do this? Should I listen on IPv6 first, then try IPv4 and note whether it succeeded?

By default, when you listen on IPv6, the server runs in dual stack mode so the following listens on IPv4 too:

using Sockets

port = 8080

server = Sockets.TCPServer()
bind(server, ip"::", port)
listen(server)

If you want them separate (like in your example) you need to disable dual stack mode when listening on IPv6. There is a keyword argument to bind which enables this, but that argument isn’t surfaced up to listen (perhaps it should, would be an easy contribution) so you need to do something like this:

using Sockets

port = 8080

# IPv4 (this could just as well be `srv4 = listen(ip"0", port)`)
srv4 = Sockets.TCPServer()
bind(srv4, ip"0", port)
listen(ip"0", port)

# IPv6
srv6 = Sockets.TCPServer()
bind(srv6, ip"::", port, ipv6only = true)
listen(srv6)
1 Like

Which operating system? Have you tried it on BSD?

No this was on Linux.

Okay, I’ll assume that BSD doesn’t do dual stack. I should try both listens, in case someone else bound the port (maybe two copies of the program are running).