Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在不使用Golang中的HTTP库的情况下获得HTTP响应?_Go_Systems Programming - Fatal编程技术网

如何在不使用Golang中的HTTP库的情况下获得HTTP响应?

如何在不使用Golang中的HTTP库的情况下获得HTTP响应?,go,systems-programming,Go,Systems Programming,我正在努力学习系统编程。我想知道如何在不使用任何库(如HTTP)的情况下对URL发出GET请求。任何帮助都将不胜感激 如果您直接使用套接字,这会非常容易;HTTP是一个非常简单的协议。下面是使用HTTP 1.1对端口80处给定主机的HTTP GET: package main import ( "fmt" "io/ioutil" "log" "net" "net/u

我正在努力学习系统编程。我想知道如何在不使用任何库(如HTTP)的情况下对URL发出GET请求。任何帮助都将不胜感激

如果您直接使用套接字,这会非常容易;HTTP是一个非常简单的协议。下面是使用HTTP 1.1对端口80处给定主机的HTTP GET:

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net"
    "net/url"
    "os"
)

func main() {
    s := os.Args[1]
    u, err := url.Parse(s)
    if err != nil {
        log.Fatal(err)
    }

    conn, err := net.Dial("tcp", u.Host+":80")
    if err != nil {
        log.Fatal(err)
    }

    rt := fmt.Sprintf("GET %v HTTP/1.1\r\n", u.Path)
    rt += fmt.Sprintf("Host: %v\r\n", u.Host)
    rt += fmt.Sprintf("Connection: close\r\n")
    rt += fmt.Sprintf("\r\n")

    _, err = conn.Write([]byte(rt))
    if err != nil {
        log.Fatal(err)
    }

    resp, err := ioutil.ReadAll(conn)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(resp))

    conn.Close()
}
也就是说,整个HTTP协议有许多不同的选项和变体,需要花费大量的时间、精力和调优来实现


Go的源代码通常相当容易理解,因此您可以阅读net/http的代码。也有使用较低层实现的可选HTTP包,例如

您的问题基本上是如何实现HTTP协议,这是一个非常广泛的问题。这方面有实际的标准,请参阅RFC 7230了解HTTP/1.1。这意味着您需要阅读文档以理解协议,然后需要在套接字之上实现该协议。如果你想在没有库的情况下实现HTTPS,你还需要自己实现TLS——这比HTTP还要复杂。想了解一下Go中现有的协议实现,这些都是开源的。你想自己从头开始创建HTTP客户端吗?非常感谢你的帮助!如何从整个响应,甚至只是HTML中获取错误代码或响应代码?除了正常的文本解析,还有什么方法可以得到这个结果吗?@AdityaGaikwad:你只需要从响应的第一行开始解析它就可以了,这又是一次失败!如果我使用-var buf bytes.Buffer io.Copy&buf,conn,然后检查buf的长度,它与resp的长度不同。你能告诉我为什么会这样吗?那么,哪一种读取响应字节数更好或更准确?@AdityaGaikwad:我不确定你指的是哪种代码,但这听起来像是一个完全不同的问题。io.Copy和ioutil.ReadAll都是在EOF之前读取的,区别在于数据的返回方式/写入位置。