英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论