client
package main
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"sync"
"time"
)
var wg sync.WaitGroup
//http://test.test.com/go/web/http/test.php
func main() {
//test()
//getTest()
postTest()
//test2()
}
func test() {
//resp, _ := http.Get("http://www.baidu.com")
//fmt.Println(resp)
resp, _ := http.Get("http://127.0.0.1:8000/go")
defer resp.Body.Close()
// 200 OK
fmt.Println(resp.Status)
fmt.Println(resp.Header)
buf := make([]byte, 1024)
for {
// 接收服务端信息
n, err := resp.Body.Read(buf)
if err != nil && err != io.EOF {
fmt.Println(err)
return
} else {
fmt.Println("读取完毕")
res := string(buf[:n])
fmt.Println(res)
break
}
}
}
func getTest() {
//apiUrl := "http://test.test.com/go/web/http/test.php?name=qwe"
apiUrl := "http://127.0.0.1:8000/gets?name=qwe"
//get请求参数
data := url.Values{}
data.Set("sex", "10") //Set方法将key对应的值集设为只有value,它会替换掉已有的值集。
data.Set("sex", "0")
data.Set("age", "99")
data.Set("age2", "98")
data.Add("sex", "1") //&sex=0&sex=1 Add将value添加到key关联的值集里原有的值的后面。
data.Del("age2")
data.Set("arr[0]", "1")
data.Set("arr[2]", "3")
u, err := url.ParseRequestURI(apiUrl)
if err != nil {
fmt.Printf("parse url requestUrl failed,err:%v\n", err)
}
fmt.Printf("parse url requestUrl %v\n", u) //http://test.test.com/go/web/http/test.php?name=qwe
u.RawQuery = data.Encode() //Encode方法将v编码为url编码格式("bar=baz&foo=quux"),编码时会以键进行排序。
//原name参数失效
fmt.Println(u.String()) //http://test.test.com/go/web/http/test.php?age=99&arr%5B0%5D=1&arr%5B2%5D=3&sex=0&sex=1
//get
resp, err := http.Get(u.String())
if err != nil {
fmt.Println("get failed, err:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("read from resp.Body failed,err:", err)
return
}
fmt.Println(string(body))
}
func postTest() {
//apiUrl := "http://test.test.com/go/web/http/test.php?name=qwe"
apiUrl := "http://127.0.0.1:8000/posts?name=qwe"
//get请求参数
data := url.Values{}
data.Set("sex", "10") //Set方法将key对应的值集设为只有value,它会替换掉已有的值集。
data.Set("sex", "0")
data.Set("age", "99")
data.Set("age2", "98")
data.Add("sex", "1") //&sex=0&sex=1 Add将value添加到key关联的值集里原有的值的后面。
data.Del("age2")
data.Set("arr[0]", "1")
data.Set("arr[2]", "3")
u, err := url.ParseRequestURI(apiUrl)
if err != nil {
fmt.Printf("parse url requestUrl failed,err:%v\n", err)
}
fmt.Printf("parse url requestUrl %v\n", u) //http://test.test.com/go/web/http/test.php?name=qwe
fmt.Println(u.RawQuery) //name=qwe
u.RawQuery = data.Encode() //Encode方法将v编码为url编码格式("bar=baz&foo=quux"),编码时会以键进行排序。
//原参数失效
fmt.Println(u.String()) //http://test.test.com/go/web/http/test.php?age=99&arr%5B0%5D=1&arr%5B2%5D=3&sex=0&sex=1
//func Post(url string, bodyType string, body io.Reader) (resp *Response, err error)
//func PostForm(url string, data url.Values) (resp *Response, err error)
resp, err := http.PostForm(u.String(), data)
if err != nil {
fmt.Println("post failed, err:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("read from resp.Body failed,err:", err)
return
}
fmt.Println(string(body))
}
func test2() {
fun1 := func() {
defer wg.Done() //计数器-1
ew, _ := http.Get("http://cqwz.cqnews.net/ask/askDetailCount?id=385107")
defer ew.Body.Close()
}
for j := 0; j < 100; j++ {
for i := 0; i < 100; i++ {
wg.Add(1)
go fun1()
}
time.Sleep(3 * time.Millisecond)
}
wg.Wait()
}
server
package main
import (
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
)
func main() {
//http://127.0.0.1:8000/go
// 单独写回调函数
http.HandleFunc("/go", myHandler)
http.HandleFunc("/gets", myHandlerGet)
http.HandleFunc("/posts", myHandlerPost)
http.HandleFunc("/post/file", myHandlerPostFile)
// addr:监听的地址
// handler:回调函数
err := http.ListenAndServe("127.0.0.1:8000", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
// handler函数
func myHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.RemoteAddr, "连接成功") //127.0.0.1:59047 连接成功
// 请求方式:GET POST DELETE PUT UPDATE
fmt.Println("method:", r.Method) // GET
fmt.Println("url:", r.URL.Path) // /go
fmt.Println("header:", r.Header) //map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]]
fmt.Println("body:", r.Body) //body: {}
fmt.Println("scheme:", r.URL.Scheme)
// 回复
w.Write([]byte("www.baidu.com"))
}
func myHandlerGet(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
data := r.URL.Query()
fmt.Println(data) //map[age:[99] arr[0]:[1] arr[2]:[3] sex:[0 1]]
fmt.Println(data.Get("name")) //空字符串
fmt.Println(data.Get("age"))
fmt.Println(data.Get("arr[0]"))
fmt.Println(data.Get("sex"))
answer := `{"status": "ok"}`
w.Write([]byte(answer))
}
func myHandlerPost(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
data := r.URL.Query()
fmt.Println(data) //map[age:[99] arr[0]:[1] arr[2]:[3] sex:[0 1]]
fmt.Println("11 ",data.Get("name")) //空字符串
fmt.Println("11 ",data.Get("age"))
fmt.Println("11 ",data.Get("arr[0]"))
fmt.Println("11 ",data.Get("sex")) //0
//answer := `{"status": "ok"}`
//w.Write([]byte(answer))
// 1. 请求类型是application/x-www-form-urlencoded时解析form数据
//application/json时没数据
r.ParseForm()// 返回url.Values
fmt.Println(r.PostForm) // 打印form数据 map[age:[99] arr[0]:[1] arr[2]:[3] sex:[0 1]]
fmt.Println(r.PostForm.Get("name"), r.PostForm.Get("age"), r.PostForm.Get("arr[0]"), r.PostForm.Get("sex"))
fmt.Println(r.Form.Get("name"), r.Form.Get("age"), r.Form.Get("arr[0]")) //url.Values
// 2. 请求类型是application/json时从r.Body读取数据
b, err := ioutil.ReadAll(r.Body) //b []byte
if err != nil {
fmt.Println("read request.Body failed, err:%v\n", err)
return
}
fmt.Println(string(b))
//----------------------------616646857926680486360950
//Content-Disposition: form-data; name="sex"
//
//10
//----------------------------616646857926680486360950
//Content-Disposition: form-data; name="age"
//
//12
//----------------------------616646857926680486360950
//Content-Disposition: form-data; name="age2"
//
//434
//----------------------------616646857926680486360950
//Content-Disposition: form-data; name="arr[0]"
//
//231
//----------------------------616646857926680486360950
//Content-Disposition: form-data; name="arr[2]"
//
//2312
//----------------------------616646857926680486360950--
answer := `{"status": "ok"}`
w.Write([]byte(answer))
}
func myHandlerPostFile(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(32 << 20)
file, handler, err := r.FormFile("file")
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
//fmt.Fprintf(w, "%v", handler.Header) //输出给用户
f, err := os.OpenFile("./test/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666) //不能自动创建路径
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
io.Copy(f, file)
answer := `{"status": "ok"}`
w.Write([]byte(answer))
}