go net: Listen总是使用nextPort()而不是期望的端口,在JS中,

gg0vcinb  于 7个月前  发布在  Go
关注(0)|答案(5)|浏览(102)

你正在使用哪个版本的Go( go version )?

$ go version
go version go1.12.1 darwin/amd64

由于这个问题与编译到WebAssembly并在Node.js中运行有关,这是我的Node.js版本:

$ node --version
v11.7.0

这个问题在最新版本中是否会重现?

是的。

你正在使用什么操作系统和处理器架构( go env )?

go env 输出

GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/alex/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/alex/programming/go"
GOPROXY=""
GORACE=""
GOROOT="/Users/alex/.go"
GOTMPDIR=""
GOTOOLDIR="/Users/alex/.go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/h1/vhbpm31925nd0whbv4qd8mr00000gn/T/go-build857099932=/tmp/go-build -gno-record-gcc-switches -fno-common"

然而,值得注意的是,只有在设置了 GOOS=js GOARCH=wasm 时才会发生这个bug。

你做了什么?

考虑以下Go程序:

package main

import (
	"fmt"
	"net"
)

func main() {
	ln, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
		panic(err)
	}
	defer ln.Close()
	fmt.Println(ln.Addr())
}

用以下命令运行程序(来自 Go WebAssembly Wiki ):

GOOS=js GOARCH=wasm go run -exec="$(go env GOROOT)/misc/wasm/go_js_wasm_exec" main.go

你期望看到什么?

程序应该输出 127.0.0.1:8080 ,因为这是我传递给 net.Listen 的地址。
如果你用 go run main.go (不编译为WebAssembly)运行程序,你会看到我所期望的输出。

你看到了什么?

127.0.0.1:1

我认为问题的根本在于 net_fake.go 中的 socket 函数。它总是使用 nextPort() 而不是使用 laddr 参数中的端口。

xhv8bpkk

xhv8bpkk1#

是的,我理解这个实现是假的。然而,似乎有一些努力让它工作起来,更正端口号会使它更有用。
具体来说,我正在为Go代码编写一些测试,我想确保它在编译成WebAssembly时能正常工作。有很多代码需要测试,但在底层,我试图拨打一个 net.Listener 。由于拨打(这只是我想测试功能的一部分)不能正确工作,整个测试失败。
如果 http://golang.org/cl/120958 能解决这个问题,我可以等待。有人知道什么时候可能会发布吗?

t3psigkw

t3psigkw2#

请问何时会发布?
我会尝试赶上Go 1.13的发布。请注意,像我这样的外籍贡献者的CL可能需要较长时间才能发布,有时可能需要一两年,就像CL 120958在去年的世界杯期间编写的,但至今仍未审查。

h7appiyu

h7appiyu3#

@neelance,我认为你在这里最了解情况。如果有任何我能帮忙的地方,请告诉我!

ewm0tg9j

ewm0tg9j4#

以下是另一个实际使用监听器而不是仅仅打印出 ln.Addr() 的程序示例:

package main

import (
	"fmt"
	"io/ioutil"
	"net"
)

func main() {
	ln, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
		panic(err)
	}
	defer ln.Close()
	fmt.Println(ln.Addr())

	go func() {
		conn, err := net.Dial("tcp", "127.0.0.1:8080")
		if err != nil {
			panic(err)
		}
		defer conn.Close()
		if _, err := conn.Write([]byte("Hello!")); err != nil {
			panic(err)
		}
	}()

	fmt.Println("Waiting for new connections...")
	conn, err := ln.Accept()
	if err != nil {
		panic(err)
	}
	bytes, err := ioutil.ReadAll(conn)
	if err != nil {
		panic(err)
	}
	fmt.Println("Received: ", string(bytes))
}

使用 go run main.go 运行:

127.0.0.1:8080
Waiting for new connections...
Received:  Hello!

使用 GOOS=js GOARCH=wasm go run -exec="$(go env GOROOT)/misc/wasm/go_js_wasm_exec" main.go 运行:

127.0.0.1:1
Waiting for new connections...
panic: dial tcp 127.0.0.1:8080: Connection refused

goroutine 6 [running]:
main.main.func1()
	/Users/alex/programming/go/src/github.com/albrow/wasm-listen-port-bug/main.go:20 +0x25
created by main.main
	/Users/alex/programming/go/src/github.com/albrow/wasm-listen-port-bug/main.go:17 +0x17
exit status 2

有趣的是,如果你将代码更改为 net.Listen("tcp", "127.0.0.1:1")net.Dial("tcp", "127.0.0.1:1"),因为这是 nextPort() 首先返回的端口。

bfrts1fy

bfrts1fy5#

See #30324 .
The package net on JS is fake and incomplete. I guess http://golang.org/cl/120958 fixes this issue.

相关问题