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的请求体
- URL.Query(): 返回query string
- 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)
}