go基础库之连接到 HTTP 服务器

前面分享了 “连接到远程服务器” 让我们了解了如何连接 TCP 服务器。本文,将展示更高级别的 HTTP 服务器的通信。

go基础库之连接到 HTTP 服务器

Golang 版本

1.14.2

前言

前面分享了 “连接到远程服务器” 让我们了解了如何连接 TCP 服务器。本文,将展示更高级别的 HTTP 服务器的通信。

实现


package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
)

type StringServer string

func (s StringServer) ServeHTTP(rw http.ResponseWriter,
	req *http.Request) {
	req.ParseForm()
	fmt.Printf("Received form data: %v\n", req.Form)
	rw.Write([]byte(string(s)))
}

func createServer(addr string) http.Server {
	return http.Server{
		Addr: addr,
		Handler: StringServer("Hello world"),
	}
}

const addr = "localhost:9090"

func main() {
	s := createServer(addr)
	go s.ListenAndServe()

	useRequest()
	simplePost()

}

func simplePost() {
	res, err := http.Post("http://localhost:9090",
		"application/x-www-form-urlencoded",
		strings.NewReader("name=test&surname=abc"))
	if err != nil {
		panic(err)
	}

	data, err := ioutil.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	res.Body.Close()
	fmt.Println("Response from server:" + string(data))
}

func useRequest() {

	hc := http.Client{}
	form := url.Values{}
	form.Add("name", "test")
	form.Add("surname", "abc")

	req, err := http.NewRequest("POST",
		"http://localhost:9090",
		strings.NewReader(form.Encode()))
	req.Header.Add("Content-Type",
		"application/x-www-form-urlencoded")

	res, err := hc.Do(req)

	if err != nil {
		panic(err)
	}

	data, err := ioutil.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	res.Body.Close()
	fmt.Println("Response from server:" + string(data))
}




$ go run main.go

Received form data: map[name:[test] surname:[abc]]
Response from server:Hello world
Received form data: map[name:[test] surname:[abc]]
Response from server:Hello world

原理

连接到 HTTP 服务器可以在 net/http 包的帮助下完成。 当然,还有更多的方法可以实现这一点,但是上面的代码展示了两种最常用的方法。 第一个选项实现了 simplePost 函数,并演示了默认客户端的使用。 这里选择 POST 方法是因为它比 GET 更复杂。 Post 方法以 Reader 的形式接受 URL、内容类型和主体。 调用 Post 函数会立即请求服务器并返回结果。

Userequest 函数实现了相同的功能,但是使用了可定制的 API 和它自己的 Client 实例。 实现利用 NewRequest 函数根据这些给定的参数创建请求: 方法、 URL 和请求主体。 内容类型必须单独设置为 Header 属性。 请求使用在 Client 上创建的 Do 方法执行。