服務端 package main import ( "errors" "fmt" "log" "net" "net/rpc" "net/rpc/jsonrpc" "os" ) // 算數運算結構體 type Arith struct { } // 算數運算請求結構體 type ArithReques ...
服務端
package main
import (
"errors"
"fmt"
"log"
"net"
"net/rpc"
"net/rpc/jsonrpc"
"os"
)
// 算數運算結構體
type Arith struct {
}
// 算數運算請求結構體
type ArithRequest struct {
A int
B int
}
// 算數運算響應結構體
type ArithResponse struct {
Pro int // 乘積
Quo int // 商
Rem int // 餘數
}
// 乘法運算方法
func (this *Arith) Multiply(req ArithRequest, res *ArithResponse) error {
res.Pro = req.A * req.B
return nil
}
// 除法運算方法
func (this *Arith) Divide(req ArithRequest, res *ArithResponse) error {
if req.B == 0 {
return errors.New("divide by zero")
}
res.Quo = req.A / req.B
res.Rem = req.A % req.B
return nil
}
func main() {
rpc.Register(new(Arith)) // 註冊rpc服務
lis, err := net.Listen("tcp", "127.0.0.1:8096")
if err != nil {
log.Fatalln("fatal error: ", err)
}
fmt.Fprintf(os.Stdout, "%s", "start connection")
for {
conn, err := lis.Accept() // 接收客戶端連接請求
if err != nil {
continue
}
go func(conn net.Conn) { // 併發處理客戶端請求
fmt.Fprintf(os.Stdout, "%s", "new client in coming\n")
jsonrpc.ServeConn(conn)
}(conn)
}
}
go標準庫客戶端
package main
import (
"fmt"
"log"
"net/rpc/jsonrpc"
)
// 算數運算請求結構體
type ArithRequest struct {
A int
B int
}
// 算數運算響應結構體
type ArithResponse struct {
Pro int // 乘積
Quo int // 商
Rem int // 餘數
}
func main() {
conn, err := jsonrpc.Dial("tcp", "127.0.0.1:8096")
if err != nil {
log.Fatalln("dailing error: ", err)
}
req := ArithRequest{9, 2}
var res ArithResponse
err = conn.Call("Arith.Multiply", req, &res) // 乘法運算
if err != nil {
log.Fatalln("arith error: ", err)
}
fmt.Printf("%d * %d = %d\n", req.A, req.B, res.Pro)
err = conn.Call("Arith.Divide", req, &res)
if err != nil {
log.Fatalln("arith error: ", err)
}
fmt.Printf("%d / %d, quo is %d, rem is %d\n", req.A, req.B, res.Quo, res.Rem)
}
通用客戶端
主要是下麵這種方式,其他任何語言都可以使用tcp封裝入參和並且解析返回數據,因為入參和返回值都可以通過json進行解析
package main
import (
"encoding/json"
"fmt"
"net"
)
func main() {
err := f()
if err != nil {
panic(err)
}
}
func f() error {
c, err := net.Dial("tcp", "127.0.0.1:8096")
if err != nil {
return err
}
defer c.Close()
type clientRequest struct {
Method string `json:"method"`
Params [1]any `json:"params"`
Id uint64 `json:"id"`
}
b, err := json.Marshal(clientRequest{
Method: "Arith.Divide",
Params: [1]any{json.RawMessage(`{"A":123,"B":31}`)},
Id: 1,
})
if err != nil {
return err
}
_, err = c.Write(b)
if err != nil {
return err
}
var clientResponse struct {
Id uint64 `json:"id"`
Result *json.RawMessage `json:"result"`
Error any `json:"error"`
}
err = json.NewDecoder(c).Decode(&clientResponse)
if err != nil {
return err
}
fmt.Println(clientResponse)
var ArithResponse struct {
Pro int // 乘積
Quo int // 商
Rem int // 餘數
}
err = json.Unmarshal(*clientResponse.Result, &ArithResponse)
if err != nil {
return err
}
fmt.Println(ArithResponse)
return nil
}
作者:janbar
出處:https://www.cnblogs.com/janbar
本文版權歸作者和博客園所有,歡迎轉載,轉載請標明出處。喜歡我的文章請 [關註我] 吧。
如果您覺得本篇博文對您有所收穫,可點擊 [推薦] 並 [收藏] ,或到右側 [打賞] 里請我喝杯咖啡,非常感謝。