go 1.13+ 是硬性门槛,需确认版本并执行 go mod init 初始化模块;服务端必须用指针接收者和指针参数注册方法,http 路径固定为 /rpc2,客户端调用格式为 "type.method"。

Go 1.13+ 是硬性门槛,低于这个版本的 go mod 行为不可靠,net/rpc 的 HTTP handler 在旧版本中也存在路径注册不一致问题 —— 直接导致客户端 rpc.DialHTTP 连不上。
确认 Go 版本并启用模块模式
运行 go version,输出必须是 go version go1.13 或更高。若不是,升级 Go 再继续。
新建项目目录后,立刻执行:
go mod init example.com/rpc-demo
这一步不能跳过,否则 rpc.Register() 在某些 Go 版本下会静默失败(尤其 1.16+ 默认开启 module-aware 模式)。
-
go.mod文件必须存在,哪怕只有一行module example.com/rpc-demo - 不要用
go get github.com/xxx手动拉依赖 ——net/rpc是标准库,无需额外安装 - 如果 IDE 提示 “cannot find package”,大概率是没初始化 module
服务端必须用指针接收者 + 指针参数
net/rpc 对方法签名极其敏感:任何非指针接收者、非指针参数、非 error 返回都会被忽略,且不报错 —— 服务启动成功,但方法根本不可调用。
正确写法:
type Arith int
<p>func (t <em>Arith) Multiply(args </em>Args, reply <em>int) error {
</em>reply = args.A * args.B
return nil
}</p>
-
args和reply都必须是指针类型(*Args,*int) - 接收者
t必须是指针(*Arith),不能是Arith -
Args结构体字段必须首字母大写(可导出),否则序列化为空
错误示范:func (t Arith) Multiply(args Args, reply int) error —— 这个方法会被 rpc.Register() 完全跳过。
HTTP 方式暴露 RPC 时路径固定为 /RPC2
很多人卡在客户端连不上,根源是误以为路径是 /rpc 或 /。Go 标准库的 rpc.HandleHTTP() 实际注册了两个 handler:
-
http.DefaultServeMux下的/RPC2—— 真正的 RPC 请求入口 -
/debug/rpc—— 仅用于调试,返回服务注册列表
所以服务端启动代码必须是:
rpc.Register(new(Arith))
rpc.HandleHTTP()
http.ListenAndServe(":8080", nil)
客户端必须用:
client, err := rpc.DialHTTP("tcp", "127.0.0.1:8080")
注意:DialHTTP 第二个参数是地址(含端口),不是路径;它内部会自动拼 /RPC2。如果手写 http://... 或改用 rpc.Dial("tcp", ...),就完全走不通。
客户端调用必须带完整服务名.方法名
Call 的第一个参数不是函数名,而是 "Arith.Multiply" 这种格式 —— 结构体名(注册时用的类型名)加点加方法名。
常见错误:
-
client.Call("Multiply", ...)→ 报错service method not found -
client.Call("arith.Multiply", ...)(小写 arith)→ 同样找不到,因为注册的是new(Arith),类型名是Arith -
client.Call("Arith.multiply", ...)(小写方法名)→ 方法签名不匹配,被忽略
验证是否注册成功?访问 http://localhost:8080/debug/rpc,能看到类似:
{"Arith":{"Multiply":{...},"Divide":{...}}}
没看到你的方法,说明注册失败或签名不对 —— 回头检查接收者和参数指针。
最常被忽略的点:服务端启动后,客户端必须等几毫秒再 Dial(尤其 Windows),否则可能遇到 connection refused —— 不是代码问题,是 TCP socket 建立延迟。加个 time.Sleep(100 * time.Millisecond) 能避开绝大多数“连不上”的假问题。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











