server

server.go

package main

import (
    "errors"
    "fmt"
    "net"
    "net/http"
    "net/rpc"
)

type Args struct {
    A, B int
}
type Quotient struct {
    Quo, Rem int
}
type Arith int

func (t *Arith) Multiply(args *Args, reply *int) error {
    *reply = args.A * args.B
    return nil
}
func (t *Arith) Divide(args *Args, quo *Quotient) error {
    if args.B == 0 {
        return errors.New("divide by zero")
    }
    quo.Quo = args.A / args.B
    quo.Rem = args.A % args.B
    return nil
}
func main() {
    arith := new(Arith)
    rpc.Register(arith)
    rpc.HandleHTTP() // http 实现
    err := http.ListenAndServe(":1234", nil) // http rpc 监听
    if err != nil {
        fmt.Println(err.Error())
    }
}

// TCP 实现
//func main() {
//    arith := new(Arith)
//    rpc.Register(arith)
//    tcpAddr, err := net.ResolveTCPAddr("tcp", ":1234")
//    checkError(err)
//    listener, err := net.ListenTCP("tcp", tcpAddr)
//    checkError(err)
//    for {
//        conn, err := listener.Accept()
//        if err != nil {
//            continue
//        }
//        rpc.ServeConn(conn)
//    }
//}
//func checkError(err error) {
//    if err != nil {
//        fmt.Println("Fatal error ", err.Error())
//        os.Exit(1)
//    }
//}

client

client.go

package main

import (
    "fmt"
    "log"
    "net/rpc"
    "net/rpc/jsonrpc"
    "os"
    //"os"
)

type Args struct {
    A, B int
}
type Quotient struct {
    Quo, Rem int
}

func main() {
    //if len(os.Args) != 2 {
    //    fmt.Println("Usage: ", os.Args[0], "server")
    //    os.Exit(1)
    //}
    //serverAddress := os.Args[1]
    serverAddress := "localhost"
    client, err := rpc.DialHTTP("tcp", serverAddress+":1234")
    if err != nil {
        log.Fatal("dialing:", err)
    }

    // Synchronous call
    args := Args{17, 8}
    var reply int
    // 核心: 调用 Arith.Multiply 方法,传参
    err = client.Call("Arith.Multiply", args, &reply)
    if err != nil {
        log.Fatal("arith error:", err)
    }
    fmt.Printf("Arith: %d*%d=%d\n", args.A, args.B, reply)
    var quot Quotient
    // 核心: 调用 Arith.Multiply 方法,传参
    err = client.Call("Arith.Divide", args, &quot)
    if err != nil {
        log.Fatal("arith error:", err)
    }
    fmt.Printf("Arith: %d/%d=%d remainder %d\n", args.A, args.B, quot.Quo, quot.Rem)
}

// json-rpc  实现
//func main() {
//    //if len(os.Args) != 2 {
//    //fmt.Println("Usage: ", os.Args[0], "server:port")
//    //log.Fatal(1)
//    //}
//    //service := os.Args[1]
//    service := ":1212"

//TCP 实现
//client, err := rpc.Dial("tcp", service)
//if err != nil {
//log.Fatal("dialing:", err)
//}

//    client, err := jsonrpc.Dial("tcp", service)
//    if err != nil {
//        log.Fatal("dialing:", err)
//    }
//
//    // Synchronous call
//    args := Args{17, 8}
//    var reply int
//    err = client.Call("Arith.Multiply", args, &reply)
//    if err != nil {
//        log.Fatal("arith error:", err)
//    }
//    fmt.Printf("Arith: %d*%d=%d\n", args.A, args.B, reply)
//    var quot Quotient
//    err = client.Call("Arith.Divide", args, &quot)
//    if err != nil {
//        log.Fatal("arith error:", err)
//    }
//    fmt.Printf("Arith: %d/%d=%d remainder %d\n", args.A, args.B, quot.Quo, quot.Rem)
//}