質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

解決済

Go:関数外で呼んだRPCクライアントでRPCを実行できない

kkasou
kkasou

総合スコア1

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

1回答

0リアクション

0クリップ

523閲覧

投稿2022/10/01 11:00

前提

golangで下記のようなコードを書いたところ、RPCでサーバー側の関数を実行できず困っています。どうにかして大量のclientを管理したくて下記のようなコードにしたのですが、動いていません。
https://pkg.go.dev/net/rpc からそのまま引っ張ってきたコードは動くのですが、下記コードは動かず、違いがわかりません。
どうして動かないのかご教示いただけると幸いです。

実現したいこと

RPCをマスターしたい
RPCのClientをIPアドレスとポートで管理したい

発生している問題・エラーメッセージ

下はサーバーのmain.goを実行し、クライアントのmain.goを実行したあと数秒待ってからサーバーをinterruptしたときのそれぞれのメッセージです
(サーバー側)

bash

$ go run . ^Csignal: interrupt

(クライアント側)

bash

$ go run . getClient: {127.0.0.1 1234} Client created 2022/10/01 19:40:36 arith error:unexpected EOF exit status 1

該当のソースコード

サーバー側はGoの公式ページから引用しました。
クライアント側は同様に引用したものを改変しました。
(サーバー側main.go)

Go

package main import ( "errors" "log" "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() l, e := net.Listen("tcp", "127.0.0.1"+":1234") if e != nil { log.Fatal("listen error:", e) } http.Serve(l, nil) }

(クライアント側main.go)

Go

package main import ( "fmt" "log" "net/rpc" ) type Args struct { A, B int } type Quotient struct { Quo, Rem int } type Addre struct { Ip string Port string } type Arith int var ClientList map[Addre]*rpc.Client func main() { ClientList = make(map[Addre]*rpc.Client) client, err := getClient(Addre{"127.0.0.1", "1234"}) if err != nil { panic(err) } args := Args{7, 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", args.A, args.B, reply) } func getClient(query Addre) (client *rpc.Client, err error) { client, isexist := ClientList[query] if isexist { return client, nil } else { fmt.Println("getClient:", query) client, err = rpc.Dial("tcp4", query.Ip+":"+query.Port) fmt.Println("Client created") ClientList[query] = client if err != nil { fmt.Println("Error connecting") return nil, err } return client, nil } }

試したこと

Goのバージョン変更(1.17、1.18)、Goのキャッシュ削除とバイナリファイル再生成、WindowsやMacOS、VM上のUbuntu2つでの実行、getClientのExported化

補足情報(FW/ツールのバージョンなど)

goのバージョン(1.17、1.18でも試しました)

$ go version
go version go1.19.1 linux/amd64

OS(上のエラーメッセージのときはWSL上で実行しましたが、Windows11やMacOS上でもだめでした)

uname -a
Linux DESKTOP-RP77Q7S 5.15.62.1-microsoft-standard-WSL2 #1 SMP Wed Aug 24 22:24:20 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。