go: http服务器在OSX上无法工作

huangapple go评论79阅读模式
英文:

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调用开始):

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:

  • go版本:go1.6 darwin/amd64
  • OSX版本:10.11.4

服务器没有退出,它一直监听。

编辑3:

我尝试了"go build"和"go run" - 没有区别。

使用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

英文:

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

答案1

得分: 2

我想看一下 "ifconfig -a" 的输出。

这看起来像是一个本地配置问题;我无法在 OS X 10.11.4、Go 1.6 上重现这个问题。

我猜测一个隧道设备实际上正在使用 127.0.0.1 而不是回环设备。

英文:

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.

答案2

得分: 1

我修好了!我记得之前我试图增加我的机器上的连接限制,并应用了这里描述的更改: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程序中的非阻塞连接,它的行为是相同的

但我仍然不知道为什么它具体出了问题。

英文:

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.

答案3

得分: 0

你是否已经安装了Cisco Anyconnect?如果是的话,请找到websecurity_uninstall.sh并卸载websecurity。

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

它将端口8080转发到端口5001,你无法使用netstat、lsof或其他常用工具来查看为什么没有东西可以使用端口8080。

英文:

Do you have Cisco Anyconnect installed? If so find websecurity_uninstall.sh and uninstall websecurity

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

It forwards port 8080 to port 5001 and you cannot use netstat, lsof or any of the normal tools to see why nothing can use port 8080.

答案4

得分: 0

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

英文:

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

huangapple
  • 本文由 发表于 2016年4月11日 00:27:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/36532359.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定