Port 8888 is already bound on my (OS X 10.13.5) system, by a process running inside a docker container:
$ netstat -an | grep 8888
tcp6 0 0 ::1.8888 *.* LISTEN
tcp4 0 0 *.8888 *.* LISTEN
A python program which tries to bind to that port (using as close to the socket options of golang as I can manage), fails in the way I expect:
import socket
import fcntl
import os
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
flag = fcntl.fcntl(sock.fileno(), fcntl.F_GETFL)
fcntl.fcntl(sock.fileno(), fcntl.F_SETFL, flag | os.O_NONBLOCK)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.bind(("0.0.0.0", 8888))
sock.listen(5)
main()
fails with:
$ python test.py
Traceback (most recent call last):
File "test.py", line 15, in <module>
main()
File "test.py", line 11, in main
sock.bind(("0.0.0.0", 8888))
OSError: [Errno 48] Address already in use
But a go program creating a connection via net.Listen
does not fail, as I expect it to:
package main
import (
"fmt"
"net"
)
func main() {
_, err := net.Listen("tcp", "0.0.0.0:8888")
if err != nil {
fmt.Printf("Connection error: %s
", err)
} else {
fmt.Println("Listening")
}
}
Succeeds with:
$ go run test.go
Listening
A coworker reports that with the same setup, his Ubuntu system correctly fails the go program.
Why does this succeed on a Mac, and how can I get the net.Listen to show an error in binding to port 8888?
edit: If I occupy port 8888 with a simple go program like:
package main
import (
"log"
"net/http"
)
func main() {
log.Fatal(http.ListenAndServe("0.0.0.0:8888", nil))
}
Then test.go
correctly fails to bind to the port. However the docker process (which is running basically that ^^^) does not cause it to fail.
edit 2: If I specify "tcp4", then the program does indeed fail as I expect. If I specify "tcp6", it succeeds but netstat says it binds to *
instead of ::1
:
$ netstat -an | grep 8888
tcp6 0 0 *.8888 *.* LISTEN
tcp6 0 0 ::1.8888 *.* LISTEN
tcp4 0 0 *.8888 *.* LISTEN
So, specifying "tcp4" will solve my actual problem, but I really want to understand what the heck is going on with the "tcp46" connection type, and I can't find any documentation. Help!