Go网络开发笔记

用Go开发网络很常见,由于对系统库还不是很熟,做下简单的笔记.

网络处理

系统库模块

  • net : TCP连接 net.Conn
  • net/http : HTTP处理
    • httputil.DumpRequest/DumpResponse
  • crypto/tls : SSL/TLS处理网络数据处理

代码示例

http.Request和 http.ResponseWriter

  • Request
    • URL.Query(): 返回query string
      • Has 返回bool
      • Get 返回string
    • Body: 返回POST、PUT的请求体
  • ResponseWriter (io.Writer实现)
    • Header().Set() 设置头信息
    • WriteHeader(http.StatusBadRequest) 状态码
func getRoot(w http.ResponseWriter, r *http.Request) {

	hasFirst := r.URL.Query().Has("first")
	first := r.URL.Query().Get("first")
    // post req
	body, err := ioutil.ReadAll(r.Body)
	
	io.WriteString(w, "This is my website!\n")
}

HTTP客户端使用


    // 忽略HTTPS证书检查,因为本地用的自签名
    tr := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
    // 自定义客户端
    client := &http.Client{Transport: tr}
    payload := `{"username":"xulz"}`
    // 创建请求,注:为简单期间忽略了错误检查
    req, _ := http.NewRequest("POST", "https://xulizhao.com/api/login", bytes.NewBuffer([]byte(payload)))
    // 定制头信息
    req.Header.Set("Content-Type", "application/json")
    resp, _ := client.Do(req)
    // 记得关闭连接
    defer resp.Body.Close()
    // 把响应转换为对象
    var ret LoginResponse
    if err := json.NewDecoder(resp.Body).Decode(&ret); err != nil {
        log.Warn("error in json decode", err)
    }

TCP的例子

    type LoginReq struct {
        Username          string `json:"username"`
        Password        int    `json:"password`
    }
    // 读数据
    func handleRead(conn net.Conn) []byte {
        buf := make([]byte, 1024)
        // 注: 返回读到的字节数
        rLen, err := conn.Read(buf)
        checkError(err)
        r := buf[:rLen-1]
        // 假设前2个字节为实际数据大小
        size := binary.BigEndian.Uint32(r[:2])
        log.Debug("Recv:", string(r))
        return r
    }
    // 写数据
    func handleWrite(conn net.Conn, cmd []byte) {
        _, err := conn.Write(cmd)
        log.Debug("Sent:", string(cmd))
        checkError(err)
    }
    
    func main() {
        // 客户端忽略TLS检查
        conf := &tls.Config{InsecureSkipVerify: true}
        server := ServerHost + ":" + ServerPort
        // 建立TCP连接
        conn, err := tls.Dial("tcp", server, conf)
        checkError(err)
        defer conn.Close()
        auth := LoginReq("xulz", "password")
        handleWrite(conn, auth)
        handleRead(conn)
    }

扩展阅读