在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
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\n", 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\n", 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\n", 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\n", 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\n", r.URL.Path) } //回显服务目前为止调用的次数 func counter(w http.ResponseWriter, r *http.Request) { mu.Lock() fmt.Fprintf(w, "count %d\n", 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\n", r.Method, r.URL, r.Proto) for k, v := range r.Header { fmt.Fprintf(w, "Header[%q]=%q\n", k, v) } fmt.Fprintf(w, "Host=%q\n", r.Host) fmt.Fprintf(w, "remoteaddr=%q\n", r.RemoteAddr) if err := r.ParseForm(); err != nil { log.Print(err) } for k, v := range r.Form { fmt.Fprintf(w, "Form[%q]=%q\n", k, v) } } //回显服务目前为止调用的次数 func counter(w http.ResponseWriter, r *http.Request) { mu.Lock() fmt.Fprintf(w, "count %d\n", count) mu.Unlock() } |
请发表评论