• 《Go程序设计语言》第一章 源码


    fetch.go

    // fetch 输出从url获取的内容
    package main
    import (
    	"fmt"
    	"io/ioutil"
    	"net/http"
    	"os"
    )
    
    func main() {
    	// 获取屏幕输入的URL
    	for _, url := range os.Args[1:] {
    		resp, err := http.Get(url)// 请求url,获得响应
    		if (err != nil) {//处理响应失败情况
    			fmt.Fprint(os.Stderr, "fetch:%v
    ", err)
    			os.Exit(1)//进程退出1返回状态码1
    		}
    		//读取响应的主体内容
    		body, err := ioutil.ReadAll(resp.Body)
    		//避免资源泄露
    		resp.Body.Close()
    		//处理读取失败情况
    		if (err != nil) {
    			fmt.Fprintf(os.Stderr, "fetch:reading %s:%v
    ", url, err)
    			os.Exit(1)
    		}
    		//打印
    		fmt.Printf("%s", body)
    	}
    }
    //执行命令: go run fetch.go http://www.baidu.com


    fetchall.go

    // fetchall 并发获取url的内容并且报告耗时
    package main
    
    import (
    	"fmt"
    	"io"
    	"io/ioutil"
    	"net/http"
    	"os"
    	"time"
    )
    
    func main() {
    	//获得程序·开始时间
    	start := time.Now()
    	//创建字符串通道
    	ch := make(chan string)
    	for _, url := range os.Args[1:] {
    		//启动一个goroutine,调用fetch函数,通过通道向该goroutine发信息
    		go fetch(url, ch)
    	}
    	// 接收从ch通道过来的信息
    	for range os.Args[1:] {
    		fmt.Println(<-ch)
    	}
    	//打印程序总耗时
    	fmt.Printf("%0.2fs elapsed
    ", time.Since(start).Seconds())
    }
    
    func fetch(url string, ch chan<- string) {
    	//获得一个goroutine开始运行的时间
    	start := time.Now()
    	// 获得url的响应
    	resp, err := http.Get(url)
    	if (err != nil) {
    		ch <- fmt.Sprint(err)
    		return
    	}
    	//通过copy函数读取响应内容,将内容写入到输出流discard进行丢弃,返回字节数nbyte和错误信息
    	nbytes, err := io.Copy(ioutil.Discard, resp.Body)
    	//避免资源泄露
    	resp.Body.Close()
    	if (err != nil) {
    		ch <- fmt.Sprintf("while reading %s:%v", url, err)
    		return
    	}
    	//大致的获得该goroutine结束的耗时
    	secs := time.Since(start).Seconds()
    	//通过通道向main传送相关信息
    	ch <- fmt.Sprintf("%2fs %7d %s", secs, nbytes, url)
    }
    
    /*
    go run fetchall.go http://golang.org http://www.baidu.com  http://godoc.org
    0.069750s  201483 http://www.baidu.com
    0.514788s   11077 http://golang.org
    0.766819s    7161 http://godoc.org
    0.77s elapsed
    */
    


    server1.go

    //server1 是一个迷你回声服务器
    package main
    
    import (
    	"fmt"
    	"log"
    	"net/http"
    )
    
    func main() {
    	//回声请求调用处理函数
    	http.HandleFunc("/", handler)
    	//监听端口
    	log.Fatal(http.ListenAndServe("localhost:8080", nil))
    }
    
    func handler(w http.ResponseWriter, r *http.Request) {
    	//获得请求的url链接,得到请求路径
    	fmt.Fprintf(w, "url.path = %q
    ", r.URL.Path)
    }
    /*
    1.main函数将一个处理函数和以/开头的url链接在一起,代表所有的url都使用这个处理函数,然后启动服务器监听进入8080端口处的请求
    
    2.一个请求由一个http.Request类型的结构体表示,它包含很多关联的域,其中一个是所请求的URL
      当一个请求到达时,被转交给处理函数,并且从请求的URL提取路径部分,然后使用fmt.Fprintf格式化,然后作为响应发送出去
    
    */


    server2.go

    //server2是一个迷你的回声和计数服务器
    package main
    
    import (
    	"fmt"
    	"log"
    	"net/http"
    	"sync"
    )
    
    var mu sync.Mutex //全局计算器锁
    var count int //计算器
    
    func main() {
    	http.HandleFunc("/", handler)
    	http.HandleFunc("/count", counter)
    	log.Fatal(http.ListenAndServe("localhost:8080", nil))
    }
    //处理程序回显请求的URL的路径部分
    func handler(w http.ResponseWriter, r *http.Request) {
    	mu.Lock()
    	count++
    	mu.Unlock()
    	fmt.Fprintf(w, "url.path=%q
    ", r.URL.Path)
    }
    //回显服务目前为止调用的次数
    func counter(w http.ResponseWriter, r *http.Request) {
    	mu.Lock()
    	fmt.Fprintf(w, "count %d
    ", count)
    	mu.Unlock()
    }
    


    server3.go

    // server3 要求处理程序回显http请求
    package main
    
    import (
    	"fmt"
    	"log"
    	"net/http"
    	"sync"
    )
    
    var mu sync.Mutex //全局计算器锁
    var count int     //计算器
    
    func main() {
    	http.HandleFunc("/", handler)
    	http.HandleFunc("/count", counter)
    	log.Fatal(http.ListenAndServe("localhost:8080", nil))
    }
    
    //处理程序回显请求的URL的路径部分
    func handler(w http.ResponseWriter, r *http.Request) {
    	mu.Lock()
    	count++
    	mu.Unlock()
    
    	fmt.Fprintf(w, "%s %s %s
    ", r.Method, r.URL, r.Proto)
    	for k, v := range r.Header {
    		fmt.Fprintf(w, "Header[%q]=%q
    ", k, v)
    	}
    	fmt.Fprintf(w, "Host=%q
    ", r.Host)
    	fmt.Fprintf(w, "remoteaddr=%q
    ", r.RemoteAddr)
    	if err := r.ParseForm(); err != nil {
    		log.Print(err)
    	}
    	for k, v := range r.Form {
    		fmt.Fprintf(w, "Form[%q]=%q
    ", k, v)
    	}
    }
    
    //回显服务目前为止调用的次数
    func counter(w http.ResponseWriter, r *http.Request) {
    	mu.Lock()
    	fmt.Fprintf(w, "count %d
    ", count)
    	mu.Unlock()
    }
    



  • 相关阅读:
    第42天:焦点图
    第41天:匀速、缓动运动和图片无缝滚动
    第40天:字符串操作:截取字符串
    MyBatis一级缓存(转载)
    Mycat 做简单的读写分离(转载)
    ui设计的好网站(转载)
    Java面试常问的问题(转载)
    ios学习的博客地址
    策略模式
    dubbo框架的简单介绍
  • 原文地址:https://www.cnblogs.com/yinbiao/p/12575484.html
Copyright © 2020-2023  润新知