1. code
1.1 data.go
data.go 定义了rpc函数set、get的输入和输出的数据类型
package data
const (
OK = "OK"
ErrNoKey = "ErrNoKey"
)
type Err string
type PutArgs struct {
Key string
Value string
}
type PutReply struct {
Err Err
}
type GetArgs struct {
Key string
}
type GetReply struct {
Err Err
Value string
}
1.2 server.go
定义了kv结构,并注册到rpc端口
package main
import (
"fmt"
"log"
"net"
"net/rpc"
"sync"
"./data"
)
type KV struct {
mu sync.Mutex
data map[string]string
}
func (kv *KV) Get(args *data.GetArgs, reply *data.GetReply) error {
kv.mu.Lock()
defer kv.mu.Unlock()
val, ok := kv.data[args.Key]
if ok {
reply.Err = data.OK
reply.Value = val
} else {
reply.Err = data.ErrNoKey
reply.Value = ""
}
fmt.Printf("get(%s)=%s\n",args.Key,val)
return nil
}
func (kv *KV) Put(args *data.PutArgs, reply *data.PutReply) error {
kv.mu.Lock()
defer kv.mu.Unlock()
kv.data[args.Key] = args.Value
reply.Err = data.OK
fmt.Printf("put(%s,%s)\n",args.Key,args.Value)
return nil
}
func main() {
var kv KV
kv.data = map[string]string{}
rpcs := rpc.NewServer()
rpcs.Register(&kv)
l, e := net.Listen("tcp", ":1234")
if e != nil {
log.Fatal("listen error:", e)
}
for {
conn, err := l.Accept()
if err == nil {
go rpcs.ServeConn(conn)
} else {
break
}
}
}
1.3 client.go
client端远程可以调用server端的函数
package main
import (
"fmt"
"log"
"net/rpc"
"./data"
)
func connect() *rpc.Client {
client, err := rpc.Dial("tcp", ":1234")
if err != nil {
log.Fatal("dialing:", err)
}
return client
}
func get(key string) string {
client := connect()
args := data.GetArgs{"subject"}
reply := data.GetReply{}
err := client.Call("KV.Get", &args,&reply)
if err != nil {
log.Fatal("error:", err)
}
client.Close()
return reply.Value
}
func put(key string, val string) {
client := connect()
args := data.PutArgs{"subject", "6.824"}
reply := data.PutReply{}
err := client.Call("KV.Put", &args,&reply)
if err != nil {
log.Fatal("error:", err)
}
client.Close()
}
func main() {
put("subject", "6.824")
fmt.Printf("Put(subject, 6.824) done\n")
fmt.Printf("get(subject) -> %s\n", get("subject"))
}
2 run
liliang@liliang-win:~/rpc$ tree
.
├── client
├── client.go
├── data
│ └── data.go
├── server
└── server.go
go build server.go
go build client.go
有疑问加站长微信联系(非本文作者)