go 网络编程

如逆水行舟不进则退 · · 468 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

  • 客户端网络访问
package main

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

func main() {
  testHttpNewRequest()
}

func testHttpNewRequest()  {
  // 1.创建一个客户端
  client := http.Client{}
  // 2.创建一个请求,请求方式既可以是GET, 也可以是POST
  request, err := http.NewRequest("GET", "https://www.toutiao.com/search/suggest/initial_page/", nil)

  checkErr(err)
  // 3.客户端发送请求
  cookName := &http.Cookie{Name:"username", Value: "Steven"}
  // 添加cookie
  request.AddCookie(cookName)

  // 设置请求头
  request.Header.Set("Accept-Language", "zh-cn")
  fmt.Printf("Header:%v \n", request.Header)

  response, err := client.Do(request)
  checkErr(err)
  defer response.Body.Close()
  // 查看请求头的数据
  fmt.Printf("相应状态码:%v \n", response.StatusCode)
  // 4.操作数据
  if response.StatusCode == 200 {
   data, err := ioutil.ReadAll(response.Body)
   fmt.Println("网络请求成功")
   checkErr(err)
   fmt.Println(string(data))
  } else {
   fmt.Println("网络请求失败", response.Status)
  }
}

func checkErr(err error)  {
  fmt.Println("09-----------")
  defer func() {
    if ins,ok := recover().(error);ok { // 这种recover的使用方式
      fmt.Println("程序出现异常:", ins.Error())
    }
  }()
  if err != nil {
    panic(err)
  }

}



  • 使用client. Get()方法
package main

import (
  "fmt"
  "net/http"
)

func main() {
  testClientGet()
}

func testClientGet()  {
  // 创建客户端
  client := http.Client{}
  // 通过client去请求
  response, err := client.Get("https://www.toutiao.com/search/suggest/initial_page/")
  checkErr(err)
  fmt.Printf("响应状态码:%v \n", response.StatusCode)
  if response.StatusCode == 200 {
    fmt.Println("网络请求成功")
    defer response.Body.Close()
  }
}

func checkErr(err error)  {
  fmt.Println("09-----------")
  defer func() {
    if ins,ok := recover().(error);ok { // 这种recover的使用方式
      fmt.Println("程序出现异常:", ins.Error())
    }
  }()
  if err != nil {
    panic(err)
  }

}

  • 使用client. Post()或client.PostForm()方法
  • 使用http. Get()方法
package main

import (
  "fmt"
  "net/http"
)

func main() {
  testHttpGet()
}

func testHttpGet()  {

  response, err := http.Get("http://www.baidu.com")
  checkErr(err)
  fmt.Printf("响应状态码:%v \n", response.StatusCode)
  if response.StatusCode == 200 {
    fmt.Println("网络请求成功")
    defer response.Body.Close()
  } else {
    fmt.Println("请求失败",response.Status)
  }
}

func checkErr(err error)  {
  fmt.Println("09-----------")
  defer func() {
    if ins,ok := recover().(error);ok { // 这种recover的使用方式
      fmt.Println("程序出现异常:", ins.Error())
    }
  }()
  if err != nil {
    panic(err)
  }

}

  • 使用http. Post()或http.PostForm()方法
package main

import (
  "fmt"
  "net/http"
  "net/url"
  "strings"
)

func main() {
  testHttpPost()
}

func testHttpPost()  {
  //构建参数
  data := url.Values{
    "theCityName" : {"重庆"},
  }
  // 参数转化为body
  reader := strings.NewReader(data.Encode())
  fmt.Println(reader)
  // 发起post请求,MIME 格式
  response, err := http.Post("http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/getWeatherbyCityName",
    "application/x-www-form-urlencoded",reader)

  checkErr(err)
  fmt.Printf("响应状态码:%v \n", response.StatusCode)
  if response.StatusCode == 200 {
    fmt.Println("网络请求成功")
    defer response.Body.Close()
  } else {
    fmt.Println("请求失败",response.Status)
  }
}

func checkErr(err error)  {
  fmt.Println("09-----------")
  defer func() {
    if ins,ok := recover().(error);ok { // 这种recover的使用方式
      fmt.Println("程序出现异常:", ins.Error())
    }
  }()
  if err != nil {
    panic(err)
  }

}

  • webserver 使用http. FileServer ()方法
package main

import "net/http"

func main() {
  testFileServer()
}
func testFileServer()  {
  // 如果该路径里有index.html 文件,会优先显示html文件,否则会看到文件目录
  http.ListenAndServe(":2003",http.FileServer(http.Dir("./files/")))
}


  • 使用http. HandleFunc()方法
package main

import (
  "fmt"
  "net/http"
)

func main() {
  // 绑定路径,去触发方法
  http.HandleFunc("/index",indexHandler)
  // 绑定端口
  // 第一个参数为监听地址,第二个参数标识服务器处理程序,通常为nil, 这意味着服务端调用http.DefaultServeMux 进行处理
  err := http.ListenAndServe(":3013",nil)
  fmt.Println(err)
}

func indexHandler(w http.ResponseWriter, r *http.Request)  {
  fmt.Println("/index=======")
  w.Write([]byte("这是默认首页"))
}


  • 使用http.NewServeMux()方法
  • 服务端获取客户端请求数据
  • golang模板
  • map转JSON
package main

import (
  "encoding/json"
  "fmt"
)

func main() {
  // 定义一个map变量并初始化
  m := map[string][]string{
    "level":{"debug"},
    "message":{"file not found","stack overflow"},
  }
  fmt.Println(m)
  // 将map解析成json格式
  if data,err := json.Marshal(m);err==nil {
    fmt.Printf("%s \n", data)
  }
}
  • map 转json 缩进
package main

import (
  "encoding/json"
  "fmt"
)

func main() {
  // 定义一个map变量并初始化
  m := map[string][]string{
    "level":{"debug"},
    "message":{"file not found","stack overflow"},
  }
  fmt.Println(m)
  // 将map解析成json格式
  if data,err := json.MarshalIndent(m,""," ");err==nil {
    fmt.Printf("%s \n", data)
  }
}


  • 结构体转JSON
package main

import (
  "encoding/json"
  "fmt"
)

type DebugInfo struct {
  Level string
  Msg string
  author string // 未导出字段不会被json解析(首字母小写)
}
func main() {
  // 定义一个结构体切片并初始化
  debugInfos := []DebugInfo{
    DebugInfo{"debug", `file:"test.txt" not found`, "cynhard"} ,
    DebugInfo{"", "logic error", "Gopher"} ,
  }
  // 将结构体解析成JSON格式
  if data,err := json.Marshal(debugInfos);err == nil {
    fmt.Printf("%s \n", data)
  }
}

  • 结构体字段标签
package main

import (
  "encoding/json"
  "fmt"
)

// 可通过结构体标签,改变编码后json字符串的键名
type User struct {
  Name string `json:"_name"`
  Age int `json:"_age"`
  Sex uint `json:"-"` // 不解析
  Address string // 不改变key标签
}

var user = User {
  Name:"Steven",
  Age:35,
  Sex:1,
  Address: "北京海淀区",
}
func main() {
  arr, _ := json.Marshal(user)
  fmt.Println(string(arr))
}

  • json包在解析匿名字段
package main

import (
  "encoding/json"
  "fmt"
)

type Point struct {
  X,Y int
}
type Circle struct {
  Point
  Radius int
}
func main() {
  // 解析匿名字段
  if data, err := json.Marshal(Circle{Point{50,50},25});err == nil {
    fmt.Printf("%s \n", data)
  }
}

  • json 转切片
package main

import (
  "encoding/json"
  "fmt"
)

func main() {
  // 定义json格式的字符串
  data := `[{"Level":"debug","msg1":"file:\"test.txt\" not found"}, {"Level":"","msg2":"logic error"}]`
  var debugInfos []map[string]string
  // 将字符串解析成map切片
  json.Unmarshal([]byte(data), &debugInfos)
  fmt.Println(debugInfos)
}
  • json 转结构体
package main

import (
  "encoding/json"
  "fmt"
)

type DebugInfo struct {
  Level string
  Msg string
  author string // 未导出字段不会被json解析
}

func (debugInfo DebugInfo) String() string {
  return fmt.Sprintf("{Level:%s, Msg:%s}",debugInfo.Level,debugInfo.Msg)
}
func main() {
  // 定义json格式的字符串
  data := `[{"Level":"debug","Msg":"file:\"test.txt\" not found","author":"abc"}, {"Level":"","Msg":"logic error","author":"ddd"}]`
  var debugInfos []DebugInfo
  // 将字符串解析成结构体切片
  json.Unmarshal([]byte(data), &debugInfos)
  fmt.Println(debugInfos)
}

  • 解码时依然支持结构体字段标签,规则和编码时一样
package main

import (
  "encoding/json"
  "fmt"
)

type DebugInfo struct {
  Level string `json:"level"` // level 解码成 Level
  Msg string  `json:"message"` // message 解码成 Msg
  Author string `json:"-"` // 忽略Author
}

func (debugInfo DebugInfo) String() string {
 return fmt.Sprintf("{Level:%s, Msg:%s}",debugInfo.Level,debugInfo.Msg)
}
func main() {
  // 定义json格式的字符串
  data := `[{"level":"debug","message":"file:\"test.txt\" not found","author":"abc"}, {"level":"","message":"logic error","author":"ddd"}]`
  var debugInfos []DebugInfo
  // 将字符串解析成结构体切片
  json.Unmarshal([]byte(data), &debugInfos)
  fmt.Println(debugInfos)
}
  • 匿名字段解析
package main

import (
  "encoding/json"
  "fmt"
)

type Point struct {
  X,Y int
}
type Circle struct {
  Point
  Radius int
}

func main() {
  // 定义json格式字符串
  data := `{"X":80,"Y":80,"Radius":60}`
  var c Circle
  json.Unmarshal([]byte(data), &c)
  fmt.Println(c)
}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:如逆水行舟不进则退

查看原文:go 网络编程

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

468 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传