Go语言实现简单的RPC调用:语言学习中的远程过程调用基础

夏伟姑娘_6462

夏伟姑娘_6462

2026-08-09

292人浏览

原创

rpc.register()没生效的根本原因是类型未导出或注册时机错误:arith等结构体及方法名必须首字母大写,且rpc.register()须在net.listen()之前调用;若用registername则客户端必须严格匹配服务名,args/reply字段也须全部导出。

go语言实现简单的rpc调用:语言学习中的远程过程调用基础

rpc.Register() 为什么没生效?

服务端调用 rpc.Register() 后,客户端仍报 rpc: can't find service method,根本原因不是函数没写对,而是类型没导出或注册时机错。Go 的 RPC 只认导出(首字母大写)的类型和方法,new(Arith) 返回的是 *Arith,但若 Arith 结构体本身未导出(比如写成 arith 小写),整个类型就不可序列化,服务端压根不注册任何方法。

  • 结构体、方法名、参数类型、返回字段全部必须首字母大写(导出)
  • rpc.Register() 必须在 net.Listen() 之前调用,否则监听开始后注册无效
  • 如果用 rpc.RegisterName("Foo", obj),客户端调用时必须用 "Foo.Method",不能用类型名自动推导
  • 检查 Args 和 Quotient 等参数结构体是否所有字段都导出(A int ✅,a int ❌)

rpc.Dial("tcp", addr) 连上了却 Call 卡住或报 unexpected EOF

连接成功不代表调用能通——rpc.Dial("tcp", addr) 只建 TCP 连接,后续 Call() 依赖两端 gob 编码严格一致。常见卡住是因为服务端没真正处理连接,或客户端传参类型和服务端期望不匹配,导致 gob 解码失败,连接被静默关闭。

Go语言(Golang)1.26.0
Go语言(Golang)1.26.0

Go语言(Golang)1.26.0版本官方下载,版本号 1.26.0,适合旧项目维护、兼容性测试和指定版本开发环境搭建。

下载
  • 服务端必须对每个新连接调用 rpc.ServeConn(conn)(不能只 accept 一次);漏掉这句,客户端 Call() 就永远阻塞
  • 确保客户端传的参数是地址(&args),服务端接收参数是指针(*Args),且 reply 参数也必须是指针
  • 服务端方法签名必须为 func(*Args, *Reply) error,少一个星号或类型不对,gob 解码就会失败,表现为 unexpected EOF
  • 不要复用同一个 *rpc.Client 实例给多个 goroutine 并发 Call(),它不是线程安全的

想用 curl 或浏览器测试 RPC 接口?别试了

net/rpc 默认走纯 TCP + gob 编码,HTTP 只是可选 transport 层,且必须显式启用。直接访问 http://localhost:1234 会 404 或 405,因为服务端没注册任何 HTTP handler,更不会返回 JSON 或 HTML。

  • 要支持 HTTP,服务端得调用 http.Handle("/rpc", rpc.DefaultServer.HTTPHandler()),再用 http.ListenAndServe()
  • 客户端必须用 rpc.DialHTTP("http", "http://localhost:1234/rpc"),URL 路径必须和服务端 handler 注册路径完全一致
  • 即便走 HTTP,底层仍是 gob 编码,curl 发 raw POST 也解不开;想真用 curl,得换 net/rpc/jsonrpc 包,并配 jsonrpc.NewClient
  • Wireshark 抓到的是二进制 gob 流,没法人工 inspect;调试建议加日志打在 ServeConn 前后,或改用本地 channel 模拟(如知识库中第一个例子)快速验证逻辑

为什么本地跑通了,部署到服务器就失败?

本地用 localhost 能通,换服务器 IP 就连不上,通常不是防火墙问题,而是服务端 net.Listen("tcp", ":1234") 绑定的是 127.0.0.1(仅本机),对外不可达。

  • 改成 net.Listen("tcp", "0.0.0.0:1234") 才监听所有网卡,允许外部访问
  • 检查服务器安全组/iptables 是否放行目标端口(不只是 ping 通,TCP connect 也要通)
  • 客户端 rpc.Dial("tcp", "x.x.x.x:1234") 中的 IP 必须是服务端实际监听的外网或内网地址,不能写 localhost
  • 跨机器时,gob 类型定义必须完全一致:相同包路径、相同结构体名、相同字段顺序——哪怕只是重命名一个字段,gob 就 decode 失败
gob 编码的硬约束和 TCP 连接的裸露本质,决定了 Go 原生 net/rpc 不是“开箱即用”的分布式方案,而是一个需要亲手对齐每一处类型和协议的通信基座。

golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Go中Type关键字的用法
Go中Type关键字的用法

Go中Type关键字的用法有定义新的类型别名或者创建新的结构体类型。本专题为大家提供Go相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.06

2889

5

go怎么实现链表
go怎么实现链表

go通过定义一个节点结构体、定义一个链表结构体、定义一些方法来操作链表、实现一个方法来删除链表中的一个节点和实现一个方法来打印链表中的所有节点的方法实现链表。

2023.09.25

5727

6

go语言编程软件有哪些
go语言编程软件有哪些

go语言编程软件有Go编译器、Go开发环境、Go包管理器、Go测试框架、Go文档生成器、Go代码质量工具和Go性能分析工具等。本专题为大家提供go语言相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.13

702

5

0基础如何学go语言
0基础如何学go语言

0基础学习Go语言需要分阶段进行,从基础知识到实践项目,逐步深入。php中文网给大家带来了go语言相关的教程以及文章,欢迎大家前来学习。

2023.10.26

7485

20

Go语言实现运算符重载有哪些方法
Go语言实现运算符重载有哪些方法

Go语言不支持运算符重载,但可以通过一些方法来模拟运算符重载的效果。使用函数重载来模拟运算符重载,可以为不同的类型定义不同的函数,以实现类似运算符重载的效果,通过函数重载,可以为不同的类型实现不同的操作。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

2696

5

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

2944

5

go语言开发工具大全
go语言开发工具大全

本专题整合了go语言开发工具大全,想了解更多相关详细内容,请阅读下面的文章。

2025.06.11

6459

12

go语言引用传递
go语言引用传递

本专题整合了go语言引用传递机制,想了解更多相关内容,请阅读专题下面的文章。

2025.06.26

4117

12

go语言版本升级
go语言版本升级

本专题整合了go语言版本升级方法,想了解更多相关内容,请阅读专题下面的文章。

2025.06.27

7470

16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程