RPC 服务器

RPC 服务器被保存为 RPCserver.go, 并分为五个部分来介绍。

RPCserver.go的第一部分如下:

  1. package main
  2. import(
  3. "fmt"
  4. "math"
  5. "net"
  6. "net/rpc"
  7. "os"
  8. "sharedRPC"
  9. )

RPCserver.go 的第二部分代码如下:

  1. type MyInterface struct {}
  2. func Power(x, y float64) float64 {
  3. return math.Pow(x, y)
  4. }
  5. func (t *MyInterface) Multiply(arguments *sharedRPC.MyFloats, reply * float64) error {
  6. *reply = arguments.A1 * argumentsA2
  7. return nil
  8. }
  9. func (t *MyInterface) Power(arguments *sharedRPC.MyFloats, reply *float64) error {
  10. *reply = Power(arguments.A1, arguments.A2)
  11. return nil
  12. }

上面这段代码,RPC 服务器实现了所需接口以及名为 Power() 的辅助函数。

RPCserver.go 的第三段如下:

  1. func main() {
  2. PORT := ":1234"
  3. arguments := os.Args
  4. if len(arguments) != 1 {
  5. PORT = ":" + arguments[1]
  6. }

RPCserver.go 的第四部分代码如下:

  1. myInterface := new(MyInterface)
  2. rpc.Register(myInterface)
  3. t, err := net.ResolveTCPAddr("tcp4", PORT)
  4. if err != nil {
  5. fmt.Println(err)
  6. return
  7. }
  8. l, err := net.ListenTCP("tcp4", t)
  9. if err != nil {
  10. fmt.Println(err)
  11. return
  12. }

rpc.Register() 函数的调用使这个程序成为 RPC 服务器。但是,由于 RPC 服务器使用 TCP 协议,它仍需要调用 net.ResolveTCPAddr()net.ListenTCP()

RPCserver.go的其余代码如下:

  1. for {
  2. c, err := l.Accept()
  3. if err != nil {
  4. continue
  5. }
  6. fmt.Printf("%s\n", c.RemoteAddr())
  7. rpc.ServerConn(c)
  8. }
  9. }

RemoteAddr() 函数返回接入的 RPC 客户端 IP 地址和端口。rpc.ServerConn() 函数为 RPC 客户端提供服务。

执行 RPCserver.go 并等待 RPCclient.go 连接将产生如下输出:

  1. $ go run RPCserver.go
  2. 127.0.0.1:52289

执行 RPCclient.go 将产生如下输出:

  1. $ go run RPCclient.go localhost:1234
  2. Reply (Multiply): -8.000000
  3. Reply (Power): 0.250000