post - Golang HTTP 发布错误 : connection refused

标签 post go

我正在尝试向运行 PHP 应用程序的端口 8080 上的本地主机发送发布请求。

curl 工作正常:

curl --data "key=asdf" http://localhost:8080/

但是在 Go 中我得到以下错误:

Post http://localhost:8080: dial tcp 127.0.0.1:8080: connection refused

代码如下:

func submitForm(value string){
    resp, err := http.PostForm("http://localhost:8080", url.Values{"key": {value}})
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    _, err = ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("status = ",resp.Status)
}
submitForm("asdf")

我用 httpry 监控 http 流量,我发现没有生成 http 请求,但有一些包:

4 packets received, 0 packets dropped, 0 http packets parsed

一些事实:

  • 我的操作系统是 Linux
  • 我使用 PHP 的内置网络服务器。服务器是用这个命令启动的:

    php -S localhost:8080

最佳答案

此问题似乎已在 Go 1.6 中得到解决。作为引用,原始答案如下。


这里的问题是 Go 的 net.Dialer 仅在默认情况下建立 IPv4 连接(这似乎是一个错误),但您的 PHP 服务器在 IPv6 上监听。

当您运行 php -S localhost:8080 时,它正在做(大部分)正确的事情并绑定(bind)到 IPv6 地址 ::1。它不绑定(bind)到 IPv4。

这对大多数软件来说不是问题,knows to attempt IPv6 connections first , 但是当你调用 http.PostForm() 时会发生什么是 net.http 使用它的 DefaultTransport , 默认情况下使用 net.Dialer Dial() 进行传出连接。 Dial() 尝试解析地址,然后我们在 src/net/ipsock.go 的解析器中结束 deep,在那里我们发现 Go 开发人员在尝试工作时故意搞砸了围绕其他东西:

        // We'll take any IP address, but since the dialing
        // code does not yet try multiple addresses
        // effectively, prefer to use an IPv4 address if
        // possible. This is especially relevant if localhost
        // resolves to [ipv6-localhost, ipv4-localhost]. Too
        // much code assumes localhost == ipv4-localhost.

这显然是个问题,因为 IPv6 应该是默认的首选协议(protocol)。 Linux 和 PHP 的行为是正确的,而 Go 本身却不是。

上面的注释是在 1.4 分支中找到的。在 master 分支中,这已被完全重写,但在新代码中,首选 IPv6 还是 IPv4 地址并不明显。它很可能是不确定的;我没有花太多时间看它。根据我在 GitHub 上发现的问题,(见下文)不太可能真正修复。

同时,您可以通过让 Go 连接到 ::1 或让 PHP 绑定(bind)到 127.0.0.1 来解决这个错误。您也可以构建自己的具有正确行为的 RoundTripper,但这可能工作量太大,除非您实际上在访问支持 IPv6 的服务时遇到问题(最终我们都会遇到问题,所以这确实需要修复)。

一些相关的 Go 问题包括:

以及其他几个不再相关的旧问题,因为代码早已被重写......

关于post - Golang HTTP 发布错误 : connection refused,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28376472/

相关文章:

post - chalice 3 : Binding multiple command objects via POST

c# - 如何从网络上的 POST 数据中读取 C# 文件

Go exec.Command() - 运行包含管道的命令

go - 函数/结构/接口(interface)名称中允许使用哪些字符?

Golang 中的 MySQL 空值

javascript - jquery POST 两次

php - 如何在 php 中使用 http post 将表单数据作为 xml 发送

php - 如果当前表单中没有表单字段,如何在我的 POST 中包含表单字段?

user-interface - GO GUI帮助(走包)

go - 如何将临时文件作为命令行参数传递