《golang笔记》第四篇-网络客户端

197 阅读2分钟

    对于很多现代应用来说,访问互联网上的信息和访问本地文件系统一样重要。Go语言在net这个强大package的帮助下提供了一系列的package来做这件事情,使用这些包可以更简单地用网络收发信息,还可以建立更底层的网络连接,编写服务器程序。在这些情景下,Go语言原生的的并发特性显得尤其好用。

    下面给出一个示例程序fetch,这个程序获取对应的url,并将其源文件打印出来。

// Fetch prints the content found at a URL
package main

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

func main() {
	//读取url
	var url string
	if len(os.Args) != 2 {
		fmt.Fprintln(os.Stderr, "Paramater number error!")
		os.Exit(1)
	} else {
		url = os.Args[1]
	}

	//get请求url
	resp, err := http.Get(url)
	if err != nil {
		fmt.Fprintf(os.Stderr, "fetch url(%s) failed: %v\n", url, err)
		os.Exit(1)
	}

	//处理请求返回内容
	data, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil {
		fmt.Fprintf(os.Stderr, "fetch: reading error: %v\n", err)
		os.Exit(1)
	}
	fmt.Printf("%s", data)
}

http.Get函数是创建HTTP请求的函数,如果获取过程没有出错,那么会在resp这个结构体中得到访问的请求结果。respBody字段包括一个可读的服务器响应流。ioutil.ReadAll函数从response中读取到全部内容,将其结果保存在变量data中,这是一个字节切片。resp.Body.Close关闭respBody流,防止资源泄露。

事实上,我们在处理服务器响应信息时只是简单的输出,当前的逻辑举个形象的例子就是:我们从输入口(服务器响应流)获取水(响应信息),放到了池子(内存)中,然后把水接到了输出口(os.Stdout)。我们完全可以直接把输入口和输出口连接起来即可,示例代码如下:

// Fetch prints the content found at a URL
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	//读取url
	var url string
	if len(os.Args) != 2 {
		fmt.Fprintln(os.Stderr, "Paramater number error!")
		os.Exit(1)
	} else {
		url = os.Args[1]
	}

	//get请求url
	resp, err := http.Get(url)
	if err != nil {
		fmt.Fprintf(os.Stderr, "fetch url(%s) failed: %v\n", url, err)
		os.Exit(1)
	}

	//处理请求返回内容
	_, err = io.Copy(os.Stdout, resp.Body)
	resp.Body.Close()
	if err != nil {
		fmt.Fprintf(os.Stderr, "fetch: reading error: %v\n", err)
		os.Exit(1)
	}
}

因为我们没有对响应信息进行处理,因此可以直接使用os.Copy将信息从可读的服务器响应流拷贝到可写的标准输出流