继续:http 服务器在 osx 上不工作

go: http server does not work on osx

example http server 对我不起作用。源代码:

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)
}

当我尝试连接时,我得到的是:

$ 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

当 nc 尝试连​​接时,tcpdump 仅显示 SYN 数据包:

$ 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

这是服务器端 dtruss 输出的最后一部分(从套接字调用开始):

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

当我 运行 nc 时不再显示任何内容,因此它甚至没有注意到连接尝试。

我没有启用防火墙,其他一切正常,只有 Go 程序有这个问题(特别是我不能使用 docker-machine)

我该如何解决?

编辑: 我假设 #Err35 是:

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

...哇?

编辑2:

服务器没有退出,它会无限期地侦听。

编辑 3:

我尝试了 "go build" 和“go 运行 - 没有区别

使用 localhost 而不是 127.0.0.1 - 没有区别

改用 w.Write([]byte(fmt.Sprintf("Hi there, I love %s!", r.URL.Path[1:])) - 没有区别。顺便说一句 - 它说 nc: connectx to 127.0.0.1 port 8080 (tcp) failed: Operation timed out,所以连接尝试超时,而不是读取

ifconfig -a 和 netstat -r 输出:https://gist.github.com/mabn/ed171f180725b563d32bb86d5ec61988

我想查看 'ifconfig -a' 的输出。

这听起来像是本地配置问题;我无法在 OS X 10.11.4, Go 1.6

上重现这个

我的 W.A.G 是隧道设备实际上使用 127.0.0.1 而不是环回设备。

您是否安装了 Cisco Anyconnect?如果是这样,找到 websecurity_uninstall.sh 并卸载网络安全

sudo /opt/cisco/anyconnect/bin/websecurity_uninstall.sh

它将端口 8080 转发到端口 5001,您不能使用 netstat、lsof 或任何常规工具来查看为什么没有任何东西可以使用端口 8080。

我确定您已经检查过了,但是您是否打开了数据包过滤 (pfctl) 或其他防火墙?参见 https://superuser.com/questions/505128/deny-access-to-a-port-from-localhost-on-osx

我修好了!我记得早些时候我试图增加我机器上的连接限制并应用此处描述的更改:https://apple.stackexchange.com/a/169606

还原它们解决了问题。这就是帮助:

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

顺便说一句:经过更多调查,我发现:

  • 问题是 accept() 系统调用每次都返回 EAGAIN 但不接受任何连接
  • 对于 C 和 Java 程序中的非阻塞连接,它的行为相同

但我仍然不知道它到底为什么坏了。