转到:http服务器在osx上不起作用

The example http server doesn't work for me. Source code:

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe("127.0.0.1:8080", nil)
}

When I try to connect all I get is:

$ curl 127.0.0.1:8080
curl: (7) Failed to connect to 127.0.0.1 port 8080: Operation timed out
$ nc -v -G 5 127.0.0.1 8080
nc: connectx to 127.0.0.1 port 8080 (tcp) failed: Operation timed out

While nc tries to connect tcpdump shows only SYN packets:

$ tcpdump -i lo0 port 8080
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo0, link-type NULL (BSD loopback), capture size 262144 bytes
18:21:30.906638 IP localhost.52799 > localhost.http-alt: Flags [S], seq 3375761924, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 118569352 ecr 0,sackOK,eol], length 0
18:21:31.006824 IP localhost.52799 > localhost.http-alt: Flags [S], seq 3375761924, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 118569452 ecr 0,sackOK,eol], length 0
18:21:31.106989 IP localhost.52799 > localhost.http-alt: Flags [S], seq 3375761924, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 118569552 ecr 0,sackOK,eol], length 0
18:21:31.208141 IP localhost.52799 > localhost.http-alt: Flags [S], seq 3375761924, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 118569653 ecr 0,sackOK,eol], length 0
18:21:31.308288 IP localhost.52799 > localhost.http-alt: Flags [S], seq 3375761924, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 118569753 ecr 0,sackOK,eol], length 0
18:21:31.408336 IP localhost.52799 > localhost.http-alt: Flags [S], seq 3375761924, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 118569853 ecr 0,sackOK,eol], length 0
18:21:31.609143 IP localhost.52799 > localhost.http-alt: Flags [S], seq 3375761924, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 118570053 ecr 0,sackOK,eol], length 0
18:21:32.011215 IP localhost.52799 > localhost.http-alt: Flags [S], seq 3375761924, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 118570453 ecr 0,sackOK,eol], length 0
18:21:32.812512 IP localhost.52799 > localhost.http-alt: Flags [S], seq 3375761924, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 118571253 ecr 0,sackOK,eol], length 0
18:21:34.414686 IP localhost.52799 > localhost.http-alt: Flags [S], seq 3375761924, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 118572853 ecr 0,sackOK,eol], length 0

And here's the last part of dtruss output of the server-side (starting from socket call):

socket(0x2, 0x1, 0x0)            = 3 0
fcntl(0x3, 0x2, 0x1)             = 0 0
fcntl(0x3, 0x3, 0x0)             = 2 0
fcntl(0x3, 0x4, 0x6)             = 0 0
setsockopt(0x3, 0xFFFF, 0x20)            = 0 0
setsockopt(0x3, 0xFFFF, 0x4)             = 0 0
bind(0x3, 0xC8200BA6AC, 0x10)            = 0 0
listen(0x3, 0xFDE8, 0x10)                = 0 0
kqueue(0x3, 0xFDE8, 0x10)                = 4 0
fcntl(0x4, 0x2, 0x1)             = 0 0
kevent(0x4, 0xC8200558C0, 0x2)           = 0 0
getsockname(0x3, 0xC82005592C, 0xC820055928)             = 0 0
accept(0x3, 0xC820055AA4, 0xC820055A94)          = -1 Err#35
kevent(0x4, 0x0, 0x0)            = 0 0
select(0x0, 0x0, 0x0, 0x0, 0x700000080DE8)               = 0 0

Nothing more appears when I run nc, so it does not even notice connection attempts.

I don't have firewall enabled, everything else works, only Go programs have this issue (in particular I can't use docker-machine)

How do I fix it?

Edit: I assume that #Err35 is:

#define EDEADLK     35  /* Resource deadlock would occur */

...wat?

Edit2:

  • go: version go1.6 darwin/amd64
  • OSX: 10.11.4

The server is not exiting, it listens indefinitely.

Edit3:

I tried both "go build" and "go run - no difference

Using localhost instead of 127.0.0.1 - no difference

Using w.Write([]byte(fmt.Sprintf("Hi there, I love %s!", r.URL.Path[1:])) instead - no difference. Btw - it says nc: connectx to 127.0.0.1 port 8080 (tcp) failed: Operation timed out, so the connection attempt times out, not the read

ifconfig -a and netstat -r output: https://gist.github.com/mabn/ed171f180725b563d32bb86d5ec61988

I fixed it! I remembered that a while earlier I tried to increase limit of connections on my machine and applied the changes described here: https://apple.stackexchange.com/a/169606

Reverting them fixed the issue. This is what helped:

sudo rm /etc/sysctl.conf
sudo sysctl kern.ipc.somaxconn=128
sudo rm /Library/LaunchDaemons/limit.maxproc.plist
sudo rm /Library/LaunchDaemons/limit.maxfiles.plist

Btw: after some more investigation I found out that:

  • the problem was that accept() syscall was returning EAGAIN every time but not accepting any connections
  • it behaved the same for non-blocking connections in C and Java programs

But I still don't know why exactly it was broken.

I'd like to see the output of 'ifconfig -a'.

This smells like a local configuration issue; I can't reproduced this on OS X 10.11.4, Go 1.6

My W.A.G is that a tunnel device is actually using 127.0.0.1 not the loop back device.

I'm sure you checked this, but by any chance do you have packet filtering (pfctl) or some other firewall turned on? See https://superuser.com/questions/505128/deny-access-to-a-port-from-localhost-on-osx