Rpc调用的函数

package rpcArith

import "errors"

type RpcArithService struct {}

type Args struct {
    A, B int
}
// 第一个参数输入;第二参数输出,必须是指针类型;返回类型error
// args 代表client提供的参数,result代表要返回给调用者的计算结果
func (RpcArithService) Div(args Args, result *float64) error{
    if args.B == 0 {
        return errors.New("division by zero")
    }

    *result = float64(args.A) / float64(args.B)
    return nil
}

实现Rpc Server

package main

import (
    "log"
    "net"
    "net/rpc"
    "net/rpc/jsonrpc"

    "study.go.com/rpc"
)

func main() {
    rpc.Register(rpcArith.RpcArithService{})

    // 监听客户端发来的socket连接
    // 未链接的放入“未链接”的队列中,这些套接口处于 SYN_RCVD 状态。
    // 已链接(已经成功三次握手)的加入到“已链接”队列中,这些套接口处于 ESTABLISHED 状态。
    listener, err := net.Listen("tcp", ":1234")
    if err != nil {
        panic(err)
    }

    for {
        // 从处于 established 状态的连接队列头部取出一个已经完成的连接,
        // 如果这个队列没有已经完成的连接,accept()函数就会阻塞,处于等待状态
        conn, err := listener.Accept()
        if err != nil {
            log.Printf("accept error: %v", err)
        }

        // 取出链接后,jsonrpc.ServeConn开始工作,他是阻塞的,所以使用goroutine
        go jsonrpc.ServeConn(conn)
    }
}

实现Rpc Client

package main

import (
    "fmt"
    "net"
    "net/rpc/jsonrpc"

    "study.go.com/rpc"
)

func main() {
    // 请求链接(三次握手)
    conn, err := net.Dial("tcp", ":1234")
    if err != nil {
        panic(err)
    }

    client := jsonrpc.NewClient(conn)

    var result float64

    // 远程调用函数,等待返回结果
    err = client.Call("RpcArithService.Div", rpcArith.Args{10, 3}, &result)

    if err != nil {
        panic(nil)
    }
    fmt.Println(result)
}