go---基于HTTP协议的网络服务

http.Get

package main

import (
	"fmt"
	"net/http"
)

func main() {
	host := "baidu.com"

	url1 := "http://" + host
	fmt.Printf("Send request to %q with method GET ...\n", url1)
	// 第一个结果值的类型为 *http.Respons,为相应内容
	// 第二个结果值为 error 类型,代表了在创建和发生 HTTP 请求、接受和解析 HTTP 
	// 相应过程中可能发生的错误
	resp1, err := http.Get(url1)
	if err != nil {
		fmt.Printf("request sending error: %v\n", err)
		return
	}
	defer resp1.Body.Close()
	line1 := resp1.Proto + " " + resp1.Status
	fmt.Printf("The first line of respones:\n%s\n", line1)
	fmt.Println()
}

在这里插入图片描述

http.Client 类型中的 Transport 字段

代表着向网络发送 HTTP 请求,并从网络服务接收 HTTP 响应的操作过程。

package main

import (
	"fmt"
	"net/http"
	"net"
	"strings"
	"time"
)

func main() {
	myTransport := &http.Transport {
		Proxy: http.ProxyFromEnvironment,
		DialContext: (&net.Dialer {
			Timeout: 15 * time.Second,
			KeepAlive: 15 * time.Second, // 用于底层 socket 
			DualStack: true,
		}).DialContext,
		// 最大空闲连接数
		MaxIdleConns: 10,
		// 访问每个网络服务的最大空闲连接数
		MaxIdleConnsPerHost: 2,
		// 空闲的连接在多久后应该被关闭
		IdleConnTimeout: 30 * time.Second, 
		// 从客户端把请求完全递交给操作系统到
		// 从操作系统系统那里接收到响应报文头的最大时长
		ResponseHeaderTimeout: 0,
		// 在客户端递交了请求报文头后,等待接收第一个响应报文头的最大时长
		ExpectContinueTimeout: 1 * time.Second,
		// 基于 TLS(Transport Layer Security)协议在被建立时握手阶段的超时时间
		TLSHandshakeTimeout: 10 * time.Second,
	}
	myClient := http.Client {
		Transport: myTransport,
		Timeout: 20 * time.Second,
	}

	var logBuf strings.Builder
	var diff time.Duration
	defer func() {
		logBuf.WriteString(
			fmt.Sprintf("(elapsed time: %s)\n", diff))
		fmt.Println(logBuf.String())
	}()
	url := "https://www.baidu.com"
	logBuf.WriteString (
		fmt.Sprintf("Send request to %q with method GET ...\n", url))
	t1 := time.Now()
	resp, err := myClient.Get(url)
	diff = time.Now().Sub(t1)
	if err != nil {
		logBuf.WriteString(
			fmt.Sprintf("request sending error: %v\n", err))
		return
	}
	defer resp.Body.Close()
	line2 := resp.Proto + " " + resp.Status
	logBuf.WriteString(
		fmt.Sprintf("The first line of response:\n%s\n", line2))
}

在这里插入图片描述

http.Server 类型的 ListenAndServer 方法

http.Server 类型的 ListenAndServe 方法的功能是:监听一个基于 TCP 协议的网络地址,并对接收到的 HTTP请求进行处理。

如果 Addr 字段正确,调用 net.Listen() 在网络地址上启动基于 TCP 协议的监听,然后检查 net.Listen() 返回的错误值,如果为 nil,调用 Serve() 准备接受和处理即将到来的 HTTP 请求。Serve() 会在一个 for 中不断调用 Accept()。

package main

import (
	"fmt"
	"log"
	"net/http"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	wg.Add(2)

	go startServer1(&wg)
	go startServer2(&wg)

	wg.Wait()
}

func startServer1(wg *sync.WaitGroup) {
	defer wg.Done()
	var httpServer1 http.Server
	httpServer1.Addr = "127.0.0.1:8080"
	// 由于没有定制 handler,所以响应 404
	if err := httpServer1.ListenAndServe(); err != nil {
		if err == http.ErrServerClosed {
			log.Println("HTTP server 1 closed.")
		} else {
			log.Printf("HTTP server 1 error: %v\n", err)
		}
	}
}

func startServer2(wg *sync.WaitGroup) {
	defer wg.Done()
	mux1 := http.NewServeMux()
	mux1.HandleFunc("/hi", func(w http.ResponseWriter, req *http.Request) {
		if req.URL.Path != "/hi" {
			http.NotFound(w, req)
			return
		}
		name := req.FormValue("name")
		if name == "" {
			fmt.Fprint(w, "Welcome!")
		} else {
			fmt.Fprintf(w, "Welcome, %s!", name)
		}
	})
	httpServer2 := http.Server {
		Addr: "127.0.0.1:8081",
		Handler: mux1,
	}
	if err := httpServer2.ListenAndServe(); err != nil {
		if err == http.ErrServerClosed {
			log.Println("HTTP server 2 closed.")
		} else {
			log.Printf("HTTP server 2 error: %v\n", err)
		}
	}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值