go http
server端gin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package main import ( "github.com/gin-gonic/gin" "net/http" ) func boy(c *gin.Context) { //你所需要的东西全都封装在了gin.Context里面,包括http.Request和ResponseWriter c.String(http.StatusOK, "hi boy" ) //通过gin.Context.String返回一个text/plain类型的正文 } func girl(c *gin.Context) { c.String(http.StatusOK, "hi girl" ) } func main() { // gin.SetMode(gin.ReleaseMode) //发布模式,默认是Debug模式 engine := gin.Default() //默认的engine已自带了Logger和Recovery两个中间件 engine.GET( "/" , boy) engine.POST( "/" , girl) //路由分组 oldVersion := engine.Group( "/v1" ) oldVersion.GET( "/student" , boy) //http://localhost:5656/v1/student oldVersion.GET( "/teacher" , boy) //http://localhost:5656/v1/teacher newVersion := engine.Group( "/v2" ) newVersion.GET( "/student" , girl) //http://localhost:5656/v2/student newVersion.GET( "/teacher" , girl) //http://localhost:5656/v2/teacher engine.Run( ":5656" ) } |
client 并发访问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | package main import ( "fmt" "io" "net/http" "os" "runtime" "sync" ) func client() { if resp, err := http.Get( "http://127.0.0.1:5656" ); err != nil { panic(err) } else { defer resp.Body.Close() io.Copy(os.Stdout, resp.Body) fmt.Println( "\n" , resp.StatusCode) //resp有很多参数。200状态码 } } func main() { //并发100个协程,100次访问 wg := sync.WaitGroup{} wg.Add(100) for i := 0; i < 100; i++ { go func () { defer wg.Done() client() fmt.Println( "次数" , i) }() } wg.Wait() fmt.Printf( "当前存活的协程数量%d" , runtime.NumGoroutine()) } |
server端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | package main import ( "fmt" "github.com/julienschmidt/httprouter" "io" "net/http" "os" "time" ) func handle(method string, w http.ResponseWriter, r *http.Request, params httprouter.Params) { fmt.Printf( "request method:%s\n" , r.Method) fmt.Printf( "request body:" ) io.Copy(os.Stdout, r.Body) fmt.Println() w.Write([]byte( "Hi boy you request" + method)) } func get(w http.ResponseWriter, r *http.Request, params httprouter.Params) { handle( "get" , w, r, params) } func post(w http.ResponseWriter, r *http.Request, params httprouter.Params) { time.Sleep(1 * time.Millisecond) io.Copy(os.Stdout, r.Body) for _, ck := range r.Cookies() { fmt.Println(ck.Name, ck.Value) } handle( "post" , w, r, params) } func panic(w http.ResponseWriter, r *http.Request, params httprouter.Params) { var arr []int _ = arr[1] //数组越界panic } func main() { router := httprouter.New() router.GET( "/" , get) router.POST( "/" , post) router.POST( "/user/:name/:type/*addr" , func (rw http.ResponseWriter, request *http.Request, p httprouter.Params) { fmt.Printf( "name:%s,type:%s,addr:%s\n" , p.ByName( "name" ), p.ByName( "type" ), p.ByName( "addr" )) }) router.ServeFiles( "/file/*filepath" , http.Dir( "./http/static" )) router.PanicHandler = func (w http.ResponseWriter, r *http.Request, err interface {}) { w.WriteHeader(http.StatusInternalServerError) //设置http response status fmt.Fprint(w, "error:%s" , err) } router.GET( "/panic" , panic) //http.HandleFunc("/", HelloHandler) http.ListenAndServe( ":5656" , router) } |
client get-post-client.do-post
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | package main import ( "fmt" "io" "net/http" "os" "strings" "time" ) func client() { if resp, err := http.Get( "http://127.0.0.1:5656" ); err != nil { panic(err) } else { defer resp.Body.Close() io.Copy(os.Stdout, resp.Body) fmt.Println( "\n" , resp.StatusCode) } } func client_post() { body := "hello server" if resp, err := http.Post( "http://127.0.0.1:5656/" , "text/plain" , strings.NewReader(body)); err != nil { panic(err) } else { defer resp.Body.Close() io.Copy(os.Stdout, resp.Body) fmt.Println( "\n" , resp.StatusCode) } } //client.do-post请求可以在request加多个额外的参数如cookie或者超时时间等 func client_do() { body := "hello server" request, err := http.NewRequest( "POST" , "http://127.0.0.1:5656/" , strings.NewReader(body)) if err != nil { fmt.Println(err) return } request.AddCookie(&http.Cookie{ Name: "abc" , Value: "123" , }) client := http.Client{Timeout: 100 * time.Millisecond} resp, err := client.Do(request) if err != nil { fmt.Println(err) return } else { defer resp.Body.Close() io.Copy(os.Stdout, request.Body) fmt.Println(resp.StatusCode) fmt.Println(resp.Proto) for k, v := range resp.Header { fmt.Println(k, v[0]) } } } func main() { /* wg := sync.WaitGroup{} wg.Add(20) for i := 0; i < 20; i++ { go func() { defer wg.Done() client_post() }() } wg.Wait() fmt.Printf("当前存活的协程数量%d", runtime.NumGoroutine()) */ //get client() //post //client_post() //client.do_post请求 client_do() } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架