根据下面这张图可以知道,客户端和服务端对报文进行了序列化与反序列化。具体过程可以看代码。
问题一:windows环境编译会出现,错误因此,在终端输入下面的命令行
go run .\main.go
问题二:补充main.go的解释
package main
import (
"encoding/json"
"fmt"
"geerpc"
"geerpc/codec"
"log"
"net"
"time"
)
func startServer(addr chan string) {
// pick a free port
l, err := net.Listen("tcp", ":0")
if err != nil {
log.Fatal("network error:", err)
}
log.Println("start rpc server on", l.Addr())
addr <- l.Addr().String()
geerpc.Accept(l)
}
func main() {
addr := make(chan string)
go startServer(addr)
// in fact, following code is like a simple geerpc client
conn, _ := net.Dial("tcp", <-addr)
defer func() { _ = conn.Close() }()
time.Sleep(time.Second)
// send options
_ = json.NewEncoder(conn).Encode(geerpc.DefaultOption)
cc := codec.NewGobCodec(conn)
// send request & receive response
for i := 0; i < 5; i++ {
h := &codec.Header{
ServiceMethod: "Foo.Sum",
Seq: uint64(i),
}
_ = cc.Write(h, fmt.Sprintf("geerpc req %d", h.Seq))
_ = cc.ReadHeader(h)
var reply string
_ = cc.ReadBody(&reply)
log.Println("reply:", reply)
}
}
- net.Dial()用来返回一个net.Conn实例
- go startServer(addr)创建了一个net.Listen协程,l.Addr().String()会写入addr 通道,net.Dial(“tcp”, <-addr)一旦收到监听到的地址,就返回一个net.Conn 接口的实例
- json.NewEncoder(conn).Encode(geerpc.DefaultOption) 先是创建了一个 json.NewEncoder(conn) json编码器,然后定义geerpc.DefaultOption的编码方式。
- 将cc := codec.NewGobCodec(conn) 将conn读入buff中并返回cc结构体
- cc.Write(h, fmt.Sprintf(“geerpc req %d”, h.Seq)) 写入cc,相当于客户端发送enc.Encode(h)和enc.Encode(body) 的消息头和消息体到服务端,ReadHeader 读消息头,根据消息头对消息体进行解码
参考代码可见: