web-dev-qa-db-ja.com

go:httpサーバーはosxでは機能しません

httpサーバーの例 は私には機能しません。ソースコード:

_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 */
_

...ワット?

Edit2:

  • go:バージョンgo1.6 darwin/AMD64
  • OSX:10.11.4

サーバーは終了していません。サーバーは無期限にリッスンします。

Edit3:

「ビルドする」と「実行する」の両方を試しましたが、違いはありません

127.0.0.1の代わりにlocalhostを使用-違いはありません

代わりに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

21
mabn

それを私が直した!しばらく前に、自分のマシンの接続制限を増やして、ここで説明する変更を適用しようとしたことを思い出しました: 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()syscallが毎回EAGAINを返していたが、接続を受け入れなかったことでした。
  • cとJavaプログラムの非ブロッキング接続でも同じように動作しました

しかし、なぜ正確に壊れたのかはまだわかりません。

1
mabn

'ifconfig-a'の出力を見たいのですが。

これは、ローカル構成の問題のようなにおいがします。 OS X 10.11.4、Go1.6ではこれを再現できません

私のW.A.Gは、トンネルデバイスが実際にはループバックデバイスではなく127.0.0.1を使用しているということです。

2
9nut

これを確認したと思いますが、万が一、パケットフィルタリング(pfctl)やその他のファイアウォールがオンになっていますか? https://superuser.com/questions/505128/deny-access-to-a-port-from-localhost-on-osx を参照してください

0
Clyde McQueen

Cisco Anyconnectがインストールされていますか?もしそうなら、websecurity_uninstall.shを見つけて、websecurityをアンインストールします

Sudo /opt/Cisco/anyconnect/bin/websecurity_uninstall.sh

ポート8080をポート5001に転送し、netstat、lsof、または通常のツールを使用して、ポート8080を使用できない理由を確認することはできません。

0
Harry